NSNotificationCenter:观察员名单?

Ant*_*set 24 cocoa objective-c nsnotificationcenter

是否可以获取给定通知名称的观察者(对象和选择器)列表?(NSNotificationCenter)

PDK*_*PDK 17

(iOS 9,Swift 3)如果要查找当前注册的观察者NotificationCenter,请中断并打印其调试说明:

(lldb) e print(NotificationCenter.default.debugDescription)
Run Code Online (Sandbox Code Playgroud)

输出的每一行都包含(通知)Name,Object,Observer,Options.在多个电话NotificationCenter.default.addObserver与一些NSNotification.Name会导致在此列表中的多个条目.


NB.虽然这可能在调试时证明是有用的信息,但我不建议使用此输出在运行时管理观察者.


(来源:根据useyourloaf 回答)


sta*_*ugs 14

我不认为有一种(官方的)方法来检索给定通知名称的观察者列表NSNotificationCenter.但是,您可以创建一个子类,NSNotificationCenter然后重写以下方法:

  • + defaultCenter
  • - addObserver:selector:name:object
  • - addObserverForName:object:queue:usingBlock:
  • - removeObserver:
  • - removeObserver:name:object

在实例方法的重写实现中,您将使用字典跟踪给定通知名称的观察者.在每个重写的实例方法中,您最终将调用NSNotificationCenter各自的super方法.此外,您将提供一种方法来检索您自己的给定名称的观察者列表,例如:

- (id)observerForNotificationName:(NSString *)name
Run Code Online (Sandbox Code Playgroud)

但是,这种方法存在两个问题:首先,NSMutableDictionary将所有观察者保留在一个天真的实现中,这可能与NSNotificationCenter实现的行为不同.其次,您必须更改通过[NSNotificationCenter defaultCenter](或任何其他NSNotificationCenter实例)获取默认通知中心的代码,以便使用您的自定义子类.

请注意,第一个问题是使用CFDictionary弱引用回调,一个对相应观察者具有弱引用的容器类,或者如果您在Mac OS X上的垃圾收集环境中,可解决的问题NSHashTable.


Mot*_*eor 5

没有公共API可以查询NSNotificationCenter任何对象或通知的当前观察者列表。

先前的答案概述了一个解决方案,并在NSNotificationCenter旨在收集和提供此类信息的子类中详细介绍了有关观察者所有权的细节。

但是,此解决方案只能与您自己的代码(将调用的子类)一起使用NSNotiicationCenter。在系统库和外部库中,其他使用该库NSNotificationCenter注册/注销通知的代码又如何呢?

我建议不要子类化NSNotificationCenter,而是使用一些低级的ObjC来烦杂原始的方法实现NSNotifictionCenter,然后用我们自己的实现替换它们,这将按照上一个答案的描述或多或少地起作用,并将其称为原始实现作为他们的最后一幕。

这样做的方法如下:http : //nshipster.com/method-swizzling/

然后,您可以确保获得所有通知的所有观察者,并且您的代码可移植并且可用于直接使用的第三方代码NSNotificationCenter