观察者交流模式

马尔赫克斯

我有一个非常简单的实现(3个类)来获取基础知识。但是它有Bug。

事实:它会通知ViewController,但不会通知SecondVC的屏幕。不知道为什么或在哪里!

Git:https : //github.com/marlhex/ObserverPattern

相关类别:

struct MyNotifications {
    static let broadcast = "BROADCAST"
}
import UIKit

let notificationCtr = NotificationCenter.default

class ViewController: UIViewController {

    @IBOutlet weak var myLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        notificationCtr.addObserver(self, selector: #selector(notifyObservers), name: NSNotification.Name(rawValue: MyNotifications.broadcast), object: nil)
    }
    
    @objc func notifyObservers() {
        myLabel.text = "I got Notified"
    }
    
    @IBAction func doBroadcast(_ sender: Any) {
        notificationCtr.post(name: NSNotification.Name(rawValue: MyNotifications.broadcast), object: self)
    }

}
import UIKit

class SecondVC: UIViewController {
    
    @IBOutlet weak var mySecondLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        notificationCtr.addObserver(self, selector: #selector(notifyObserverstoo), name: NSNotification.Name(rawValue: MyNotifications.broadcast), object: nil)
    }
   
    @objc func notifyObserverstoo() {
        mySecondLabel.text = "I got Notified too" //Bug only notifies one view controller
    }
}
jnpdx

您正在使用UITabBarController托管视图。系统最初仅加载需要显示的视图控制器(ViewController在这种情况下)。然后,一旦单击的选项卡SecondVC,它将加载该视图控制器。

您可以通过将一个验证这一print声明viewDidLoadSecondVC

您还可以验证,如果SecondVC在返回ViewController并按下之前导航至,则Notify在这种情况下,两个视图控制器都将收到通知。

因此,这不是错误-只是视图加载时的实现细节。

如果您想找到一种方法来确保SecondVC在加载时可以访问该信息,则有两种选择:

  1. 依赖于传播国家的不同系统
  2. required init?(coder: NSCoder)而不是放入通知侦听器viewDidLoad(在安装过程中确实会调用它)。不过,这有一个警告UILabel尚无法加载,因此您必须存储该状态以便以后加载。尝试访问mySecondLabel之前viewDidLoad会导致崩溃。

更新更新的代码,该代码在您要使用该init方法的事件中存储通知

class SecondVC: UIViewController {
    
    // MARK: - Properties
    @IBOutlet weak var mySecondLabel: UILabel?
    
    var haveBeenNotified = false //to store whether the notification has been seen
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        notificationCtr.addObserver(self, selector: #selector(notifyObserverstoo), name: NSNotification.Name(rawValue: MyNotifications.broadcast), object: nil)
    }
    
    // MARK: - Life Cycle Methods
    override func viewDidLoad() {
        super.viewDidLoad()
        
        print("Loaded second view controller")
        
        if haveBeenNotified {
            mySecondLabel?.text = "Was notified before viewDidLoad"
        }
    }
    
    // MARK: - Observer Selector Functions
    @objc func notifyObserverstoo() {
        haveBeenNotified = true
        mySecondLabel?.text = "I got Notified too"
    }

}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章