iOS 通知 - 对象参数可以是任意对象吗?
iOS Notification - Can Object Parameter Be Any Arbitrary Object?
addObserver(_:selector:name:object:)
和 post(name:object:userInfo:)
方法都包含一个 "object" 参数。相应的文档将对象参数描述为“[t]观察者想要接收其通知的对象;也就是说,只有此发送者发送的通知才会传递给观察者,”和“[t]发布通知的对象”这些描述给我的印象是对象 "parameter," 如果未设置为 nil,则必须是从中调用 post()
方法的同一对象。
然而,在实践中,post()
方法似乎可以包含任意对象作为其对象参数。同时,addObserver()
方法可以设置任意对象。因此,如果 post()
和 addObserver()
方法引用相同的任意对象(并且具有相同的 Notification.Name),它们应该用于发送和接收。在实验中,这似乎工作得很好。
在下面的示例中,Observer 注册以接收来自任意发送者的特定通知。但是,Store 是发布通知的那个。在发布通知时,Store 包含与 "sender." 观察者收到通知的对象相同的任意时刻。即使 Store(而不是任意的)是通知的 "sender",这仍然有效。
class ArbitraryData {
var data: [String] = ["some handy info"]
func getMoreInfo() {
Store.aSyncReadData(self)
}
}
class Observer {
let arbitrary = ArbitraryData()
func initiate() {
NotificationCenter.default.addObserver(self, selector: #selector(handleNotice),
name: NSNotification.Name(rawValue: "eventHappenedNotice"),
object: arbitrary)
... do stuff ...
arbitrary.getMoreInfo()
}
func handleNotice(notice: Notification) {
for infoItem in arbitrary.data {
print(infoItem)
}
}
}
class Store {
static func aSyncReadData(dataObject: ArbitraryData) {
ServerAPI.getSomeDataFromPersistentStore(completionHandler: { newData in
dataObject.data.append(newData)
NotificationCenter.default.post(NSNotification.Name(rawValue: "eventHappenedNotice"),
object: dataObject)
})
}
}
这种对任意对象的使用是否是预期功能的一部分,是否安全?或者,使用任意对象是否是一种可能导致某种故障且以后可能难以调试的故障?
我觉得你有点误解了你在做什么。
首先,在您的示例中,Store
不是发布通知的人,而是 ArbitraryData
发布通知的人。
稍微解释一下:
如果您在 register/post 通知时使用 object
参数,则仅当用于注册的对象与发布通知的对象相同时,通知才会 received/sent 。因此,如果您对 register/send 通知同时使用 name
和 object
参数,则 name
和 object
必须相等才能进行适当的通知通信。
如果您不使用 object
参数,则只对名称进行检查。
例如,在您的情况下,如果您使用两个不相等的 ArbitraryData
实例,一个用于注册,一个用于发布,您的通知将不起作用。
addObserver(_:selector:name:object:)
和 post(name:object:userInfo:)
方法都包含一个 "object" 参数。相应的文档将对象参数描述为“[t]观察者想要接收其通知的对象;也就是说,只有此发送者发送的通知才会传递给观察者,”和“[t]发布通知的对象”这些描述给我的印象是对象 "parameter," 如果未设置为 nil,则必须是从中调用 post()
方法的同一对象。
然而,在实践中,post()
方法似乎可以包含任意对象作为其对象参数。同时,addObserver()
方法可以设置任意对象。因此,如果 post()
和 addObserver()
方法引用相同的任意对象(并且具有相同的 Notification.Name),它们应该用于发送和接收。在实验中,这似乎工作得很好。
在下面的示例中,Observer 注册以接收来自任意发送者的特定通知。但是,Store 是发布通知的那个。在发布通知时,Store 包含与 "sender." 观察者收到通知的对象相同的任意时刻。即使 Store(而不是任意的)是通知的 "sender",这仍然有效。
class ArbitraryData {
var data: [String] = ["some handy info"]
func getMoreInfo() {
Store.aSyncReadData(self)
}
}
class Observer {
let arbitrary = ArbitraryData()
func initiate() {
NotificationCenter.default.addObserver(self, selector: #selector(handleNotice),
name: NSNotification.Name(rawValue: "eventHappenedNotice"),
object: arbitrary)
... do stuff ...
arbitrary.getMoreInfo()
}
func handleNotice(notice: Notification) {
for infoItem in arbitrary.data {
print(infoItem)
}
}
}
class Store {
static func aSyncReadData(dataObject: ArbitraryData) {
ServerAPI.getSomeDataFromPersistentStore(completionHandler: { newData in
dataObject.data.append(newData)
NotificationCenter.default.post(NSNotification.Name(rawValue: "eventHappenedNotice"),
object: dataObject)
})
}
}
这种对任意对象的使用是否是预期功能的一部分,是否安全?或者,使用任意对象是否是一种可能导致某种故障且以后可能难以调试的故障?
我觉得你有点误解了你在做什么。
首先,在您的示例中,Store
不是发布通知的人,而是 ArbitraryData
发布通知的人。
稍微解释一下:
如果您在 register/post 通知时使用 object
参数,则仅当用于注册的对象与发布通知的对象相同时,通知才会 received/sent 。因此,如果您对 register/send 通知同时使用 name
和 object
参数,则 name
和 object
必须相等才能进行适当的通知通信。
如果您不使用 object
参数,则只对名称进行检查。
例如,在您的情况下,如果您使用两个不相等的 ArbitraryData
实例,一个用于注册,一个用于发布,您的通知将不起作用。