编辑已解决,请参阅下面的解决方案。我仍然很好奇为什么它有效,或许你的解决方案可以解释这个?
〜
我使用NotificationCenter发布通知传递对象。
我的目标是,如果notification.object
符合某个protocol
,我可以自行解包。
问题在于测试,展开证明是不成功的,我不知道为什么。
一系列对象(有时是enum
,有时是struct
),他们遵守NotificationsPipelineProtocol
并将这些对象与通知一起发送给订阅这些通知的接收对象
因此,例如,如果我将ReleaseNote传递给Notifications Pipeline,我会让它订阅协议:
enum ReleaseNote: Float, NotificationsPipelineProtocol {
...
当我想发布NotificationCenter
时,为订阅NotificationsPipelineProtocol
的所有项目编写的扩展函数被调用:
// finishing task, wants to post completion
...
self.postCompletion()
...
调用此功能
func postCompletion() {
NotificationCenter.default.post(name: self.completionNotificationName, object: self)
}
我保证使用此功能正确接收:
@objc private func didReceiveNotificationCompletion(_ notification : Notification) {
guard let completedNotification = notification.object as? NotificationsPipelineProtocol else {
return
}
但上面的guard语句没有解包并绑定可选项,因为return
已执行。
我已将notification.object
打印到控制台,并保证它实际上已接收到预期的对象。
你可能知道为什么它不会解开?
答案 0 :(得分:1)
我已经通过将对象的访问权限从对象替换为userInfo来解决它。
我不完全确定为什么会这样,但确实有效。
发布对象
func postCompletion() {
NotificationCenter.default.post(name: self.completionNotificationName, object: nil, userInfo: ["pipelineItem": self])
}
检索对象
guard let userInfo = notification.userInfo,
let completedNotification = userInfo["pipelineItem"] as? NotificationsPipelineProtocol else {
return
}
答案 1 :(得分:0)
此工作流程应该没有任何问题,也许您正在观察/发送错误的对象?
以下是您尝试做的一个示例,您可以在游乐场中使用它来查看它是否有效。尝试将代码移动到一个操场/示例项目中,这是最简单的情况,直到找到失败点为止!
//: Playground - noun: a place where people can play
import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
protocol NotificationsPipelineProtocol {
}
class TestObserver: NotificationsPipelineProtocol {
init() {
NotificationCenter.default.addObserver(self,
selector: #selector(notificationFired(_:)),
name: nil,
object: self)
}
dynamic func notificationFired(_ notification: Notification) {
guard let object = notification.object as? NotificationsPipelineProtocol else {
return
}
print("success")
}
func fireNotification() {
NotificationCenter.default.post(name: Notification.Name(rawValue: "test"), object: self)
}
}
let observer = TestObserver()
observer.fireNotification()