当指定对象为字符串时,NotificationCenter并不总是调用观察者

问题描述

我一直在尝试检查为什么在指定String object来过滤通知时为什么有时调用我的观察者,有时却不调用我的观察者的原因。

我的原始代码

NotificationCenter.default.addobserver(self,selector: #selector(update),name: .pathContentsChanged,object: self.folder.path) // Where path is something like "/user/folder"

@objc func update()
{
    // Not always called
}

我当前的变通办法,它确认通知objectself.folder.path匹配:

NotificationCenter.default.addobserver(self,selector: #selector(pathContentsChanged(_:)),object: nil) // No object specified anymore

@objc func pathContentsChanged(_ notification: Notification)
{
    // This does get called every time
    guard let path = notification.object as? String,path == self.folder.path else
    {
        return
    }
    self.update() // notification.object and self.folder.path do match
}

String在Swift上的工作方式是固有的吗?是因为notification.object可能是桥接的Nsstring吗?

解决方法

NotificationCenter过滤通知每个对象按引用比较对象,而不是像您期望的那样按isEqual比较对象。因此,使用不同的字符串(甚至在内容上相等)发布通知可能不会导致观察者被过滤掉。

通常,String不是notification.object中要使用的对象(由于其性质,常量,桥接等)……最常见的情况是拥有一些自定义对象(拥有工作流程) )作为通知的发起者(也就是通知对象)。

如果您想在对象中包含字符串,那么是的,您的观察者必须为非过滤对象'nil',并在处理程序中有条件地采取行动。