如果在 init 期间发布,则未收到通知?
Notification not received if posted during init?
我创建了一个 example project 来演示 Notification
处理的同步性质。
通知按预期进行 - 除了在模型初始化期间发布的通知。
The Swift Programming Language (Swift 4), Two-Phase Initialization 部分解释了初始化的安全检查。在这里,它说:
Safety check 4
An initializer cannot call any instance methods, read
the values of any instance properties, or refer to self as a value
until after the first phase of initialization is complete.
初始化的第一阶段在我的示例中在调用通知方法之前完成。而且,如下图,我也试过直接调用通知。视图控制器都没有采取任何行动 - 尽管在 初始化后 调用时,视图控制器确实按预期响应。
这是我应该报告的错误吗?还是我只是在一些简单的初始化问题上脑残了?
相关型号代码如下:
class Model {
let notificationONEName = Notification.Name("NotificationONE")
let notificationTWOName = Notification.Name("NotificationTWO")
init() {
notifyObserversTWO()
NotificationCenter.default.post(name: notificationTWOName, object: self)
}
func notifyObserversONE() {
print("START \(Model.self).\(#function)")
NotificationCenter.default.post(name: notificationONEName, object: self)
print("END \(Model.self).\(#function)")
}
}
而且,这是视图控制器中的观察者端代码:
import UIKit
class ViewController: UIViewController {
let notificationONESelector = #selector(didReceiveNotificationONE)
let notificationTWOSelector = #selector(didReceiveNotificationTWO)
let model = Model()
override func viewDidLoad() {
super.viewDidLoad()
subscribeToNotifications()
model.notifyObserversONE()
model.notifyObserversTWO()
}
func subscribeToNotifications() {
NotificationCenter.default.addObserver(self,
selector: notificationONESelector,
name: model.notificationONEName,
object: model)
NotificationCenter.default.addObserver(self,
selector: notificationTWOSelector,
name: model.notificationTWOName,
object: nil)
}
@objc func didReceiveNotificationONE(notification: Notification) {
print("START \(ViewController.self).\(#function)")
exampleUtilityFunction()
print("END \(ViewController.self).\(#function)")
}
@objc func didReceiveNotificationTWO(notification: Notification) {
print("START \(ViewController.self).\(#function)")
exampleUtilityFunction()
print("END \(ViewController.self).\(#function)")
}
func exampleUtilityFunction() {
print("START \(ViewController.self).\(#function)")
print("END \(ViewController.self).\(#function)")
}
}
在 Model.init
被调用时,没有任何东西在观察它。在调用 Model()
.
很久之后才调用 subscribeToNotifications
如果您想回复此通知,您首先需要在调用 init
之前观察 object: nil
(就像您对第二个通知所做的那样)。这意味着您不能在 属性 定义中对其进行初始化。您需要调用 subscribeToNotifications
然后创建 model
.
我创建了一个 example project 来演示 Notification
处理的同步性质。
通知按预期进行 - 除了在模型初始化期间发布的通知。
The Swift Programming Language (Swift 4), Two-Phase Initialization 部分解释了初始化的安全检查。在这里,它说:
Safety check 4
An initializer cannot call any instance methods, read the values of any instance properties, or refer to self as a value until after the first phase of initialization is complete.
初始化的第一阶段在我的示例中在调用通知方法之前完成。而且,如下图,我也试过直接调用通知。视图控制器都没有采取任何行动 - 尽管在 初始化后 调用时,视图控制器确实按预期响应。
这是我应该报告的错误吗?还是我只是在一些简单的初始化问题上脑残了?
相关型号代码如下:
class Model {
let notificationONEName = Notification.Name("NotificationONE")
let notificationTWOName = Notification.Name("NotificationTWO")
init() {
notifyObserversTWO()
NotificationCenter.default.post(name: notificationTWOName, object: self)
}
func notifyObserversONE() {
print("START \(Model.self).\(#function)")
NotificationCenter.default.post(name: notificationONEName, object: self)
print("END \(Model.self).\(#function)")
}
}
而且,这是视图控制器中的观察者端代码:
import UIKit
class ViewController: UIViewController {
let notificationONESelector = #selector(didReceiveNotificationONE)
let notificationTWOSelector = #selector(didReceiveNotificationTWO)
let model = Model()
override func viewDidLoad() {
super.viewDidLoad()
subscribeToNotifications()
model.notifyObserversONE()
model.notifyObserversTWO()
}
func subscribeToNotifications() {
NotificationCenter.default.addObserver(self,
selector: notificationONESelector,
name: model.notificationONEName,
object: model)
NotificationCenter.default.addObserver(self,
selector: notificationTWOSelector,
name: model.notificationTWOName,
object: nil)
}
@objc func didReceiveNotificationONE(notification: Notification) {
print("START \(ViewController.self).\(#function)")
exampleUtilityFunction()
print("END \(ViewController.self).\(#function)")
}
@objc func didReceiveNotificationTWO(notification: Notification) {
print("START \(ViewController.self).\(#function)")
exampleUtilityFunction()
print("END \(ViewController.self).\(#function)")
}
func exampleUtilityFunction() {
print("START \(ViewController.self).\(#function)")
print("END \(ViewController.self).\(#function)")
}
}
在 Model.init
被调用时,没有任何东西在观察它。在调用 Model()
.
subscribeToNotifications
如果您想回复此通知,您首先需要在调用 init
之前观察 object: nil
(就像您对第二个通知所做的那样)。这意味着您不能在 属性 定义中对其进行初始化。您需要调用 subscribeToNotifications
然后创建 model
.