我有一个非常简单的实现(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
}
}
您正在使用UITabBarController托管视图。系统最初仅加载需要显示的视图控制器(ViewController
在这种情况下)。然后,一旦单击的选项卡SecondVC
,它将加载该视图控制器。
您可以通过将一个验证这一print
声明viewDidLoad
的SecondVC
。
您还可以验证,如果SecondVC
在返回ViewController
并按下之前导航至,则Notify
在这种情况下,两个视图控制器都将收到通知。
因此,这不是错误-只是视图加载时的实现细节。
如果您想找到一种方法来确保SecondVC
在加载时可以访问该信息,则有两种选择:
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] 删除。
我来说两句