Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detected redundant observation of #21

Closed
devkokodev opened this issue Mar 31, 2020 · 3 comments
Closed

Detected redundant observation of #21

devkokodev opened this issue Mar 31, 2020 · 3 comments

Comments

@devkokodev
Copy link

devkokodev commented Mar 31, 2020

I use gestalt same as you describe in Usage part. I don't use storyboard or xib (entire project is in code). I have custom views in my controller and every view has it's own theme also controller. When i push or present controller for first time everything is fine, but if i pop or dissmiss and push again i get "Detected redundant observation" from some view or controller. I looked up in your demo project and in appdelegate there is var disposables: [Disposable]?. I haven't implement that stuff. I check for retain cycle all views and controller deinitialized properly. Any help for Detected redundant observation??

@regexident
Copy link
Owner

self.observe(theme: \Theme.view) should only ever be called once within the lifetime of an object (i.e. self here).

Handling Disposable is only necessary for the class-level API.

@devkokodev
Copy link
Author

i tried on demo project with only two controllers this is logs

*** 0x0000000103106690 Firs view controller regiseter for theme first theme
*** 0x0000000103121190 Second view controller regiseter for theme second theme
*** 0x0000000103121190 Second view controller deinit
*** 0x0000000103113540 Second view controller regiseter for theme second theme
*** 0x0000000103113540 Second view controller deinit
*** 0x000000010301eda0 Second view controller regiseter for theme second theme
*** 0x000000010301eda0 Second view controller deinit
*** 0x000000010301eda0 Second view controller regiseter for theme second theme
*** 0x000000010301eda0 Second view controller deinit
*** 0x000000010301eda0 Second view controller regiseter for theme second theme
*** 0x000000010301eda0 Second view controller deinit
*** 0x000000010301eda0 Second view controller regiseter for theme second theme
*** 0x000000010301eda0 Second view controller deinit
*** 0x0000000103113540 Second view controller regiseter for theme second theme
*** 0x0000000103113540 Second view controller deinit

As you can see few times second view contoller has same memory address

App delegate:
window = UIWindow(frame: UIScreen.main.bounds) window?.rootViewController = UINavigationController(rootViewController: FirstViewController()) window?.makeKeyAndVisible() ThemeManager.default.theme = ApplicationTheme.light

First view controller:
`class FirstViewController: UIViewController, Themeable {

var pushButton = UIButton(frame: CGRect(x: 100, y: 500, width: 100, height: 50))

override func viewDidLoad() {
    super.viewDidLoad()
    pushButton.setTitle("push", for: .normal)
    pushButton.setTitleColor(.black, for: .normal)
    pushButton.addTarget(self, action: #selector(onPush), for: .touchUpInside)
    view.addSubview(pushButton)
    setThemeObserve()
}


    typealias Theme = FirstVCTheme

    func setThemeObserve() {
        self.observe(theme: \ApplicationTheme.firstTheme)
        print("*** \(Unmanaged.passUnretained(self).toOpaque()) Firs view controller regiseter for theme first theme")
    }

    func apply(theme: Theme) {
        view.backgroundColor = theme.backgroundColor
    }

@objc func onPush() {
    self.navigationController?.pushViewController(SecondViewController(), animated: true)
}

}`

Second view controller: `class SecondViewController: UIViewController, Themeable {

override func viewDidLoad() {
    super.viewDidLoad()

    setThemeObserve()
}

deinit {
    print("*** \(Unmanaged.passUnretained(self).toOpaque()) Second view controller deinit")
}

    typealias Theme = SecondVCTheme

    func setThemeObserve() {
        self.observe(theme: \ApplicationTheme.secondTheme)
        print("*** \(Unmanaged.passUnretained(self).toOpaque()) Second view controller regiseter for theme second theme")
    }

    func apply(theme: Theme) {
        view.backgroundColor = theme.backgroundColor
    }

}`

AplicationTheme:
`enum ThemeType: Int {
case light
case dark
}

struct ApplicationTheme: Theme {

let firstTheme: FirstVCTheme
let secondTheme: SecondVCTheme

static let light = ApplicationTheme(firstTheme: FirstVCTheme(type: .light),
                                    secondTheme: SecondVCTheme(type: .light))
                                   

static let dark = ApplicationTheme(firstTheme: FirstVCTheme(type: .dark),
                                   secondTheme: SecondVCTheme(type: .dark))

}

struct SecondVCTheme: Theme {
let backgroundColor: UIColor

init(type: ThemeType) {
    switch type {
    case .light:
        backgroundColor = .cyan
    case .dark:
        backgroundColor = .brown
    }
}

}

struct FirstVCTheme: Theme {
let backgroundColor: UIColor

init(type: ThemeType) {
    switch type {
    case .light:
        backgroundColor = .red
    case .dark:
        backgroundColor = .yellow
    }
}

}`

@regexident
Copy link
Owner

If you get "Detected redundant observation" with func viewDidLoad(), then try moving self.observe(theme: …) into the initializer instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants