Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 何时使用NSNotificationCenter_Objective C_Ios_Architecture_Observer Pattern_Nsnotificationcenter - Fatal编程技术网

Objective c 何时使用NSNotificationCenter

Objective c 何时使用NSNotificationCenter,objective-c,ios,architecture,observer-pattern,nsnotificationcenter,Objective C,Ios,Architecture,Observer Pattern,Nsnotificationcenter,我希望在单个对象的多个事件上有多个观察者(1-to-N关系) 实现此任务的机制由提供。当用于解决我的问题时,这个机制看起来太过分了 如果不使用NSNotificationCenter,我将如何手动执行此操作: - (void)addDelegate:(id<DelegateProtocol>)delegate; - (void)removeDelegate:(id<DelegateProtocol>)delegate; -(void)addDelegate:(id)de

我希望在单个对象的多个事件上有多个观察者(1-to-N关系)

实现此任务的机制由提供。当用于解决我的问题时,这个机制看起来太过分了

如果不使用
NSNotificationCenter
,我将如何手动执行此操作:

- (void)addDelegate:(id<DelegateProtocol>)delegate;
- (void)removeDelegate:(id<DelegateProtocol>)delegate;
-(void)addDelegate:(id)delegate;
-(void)removeDelegate:(id)代表;
从我的对象中添加和删除观察者

- (void)someEventFired:(NSObject<NSCopying> *)eventData
{
    for (id delegate in delegates) {
        NSObject *data = [eventData copy];
        [delegate someEventFired:data];
    }
}
-(void)someEventFired:(NSObject*)eventData
{
for(代理中的代理id){
NSObject*数据=[eventData copy];
[委托someEventFired:数据];
}
}
这种机制是直接的,易于实现,而不需要对象共享额外的字符串

  • 除了
    NSNotificationCenter
    ,iOS框架中是否有1对N委托(如C#events)的正式模式
  • 何时应使用通知中心,何时不应使用
  • 什么时候应该使用我在这里建议的实现,什么时候不应该使用

我说,NSNotificationCenter应该始终在代理模型上使用,除非您查询代理的信息(例如
-webView:shoulloadrequest:
)。它更稳定,更容易实现,并且会产生比尝试使用委托更干净的代码。另一种选择是块,这可能是好的,但当涉及到内存管理时,它们可能是一种痛苦


最后,这取决于您,但我认为,NSNotificationCenter是几乎在任何情况下都可以使用的最佳方式,如果只是针对多观察者功能的话。

NSNotificationCenter对于您的建议来说并不过分,它正是正确的解决方案。它可以防止被观察对象必须知道或关心其观察者,从而使代码更加松散耦合和干净


为通知名共享字符串很简单,如果您的观察者需要导入此标头以执行其工作,则可以在共享常量文件或观察对象的标头中定义这些字符串

按照惯例,委托可能只用于1:1关系。如果此类型的功能确实需要1:N关系,则有两个选项:

  • 正如你提到的
  • (也称为KVO)
  • 如果只关心对象的特定属性何时更改,则KVO是合适的。否则,你真的应该考虑使用<代码> NSNotificationCenter <代码>。甚至只有当特定对象通过将该对象传递到
    addObserver:selector:name:object:
    方法发布该通知时,才能通知您


    苹果在类似的场景中使用
    NSNotification
    (如为
    UITextField
    定义的通知,包括
    uitextfieldtedbegineditingnotification
    uitextfieldtedchangenotification
    ,以及
    uitextfieldtededitingnotification
    ).

    一对N的委托关系没有意义。看看

    - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
    
    比如说。如果这个对象真的有n个委托呢?它应该如何决定应该使用从所有代理返回的n个视图中的哪一个?代表们正是按照这一1对1原则行事的

    NSNotificationCenter是正确的方法。简单使用

    addObserver:selector:name:object:
    
    分别

    postNotification:
    

    这绝对不是太多的代码。对你来说,这很容易,因为中心会处理所有的电话。

    使用通知就是广播:一个发送者只发送一条信息,而谁曾经收听过,谁就会收到它。很像一个电台,没有频道(让我们暂时忘记电话)

    授权是另一回事。请求被委派者做某事的对象通常需要该请求的结果,因此委派是一种1对1的通信,总是由对象而不是委派发起(而对象可以调用方法来通知对象发起通信,即
    [tableView reloadData]

    因此,如果发送方需要取回数据,那么它就是委托。如果发送者在广播后对任何事情都不关心,那么使用通知


    如果遇到这种情况,您需要委托,但是应该有几个对象实现协议。您应该有一个委托,它保存对其他对象的引用,并代表发件人调用方法,或者您可以使用块。

    您提出的解决方案既不比使用NSNotificationCenter简单,也不是线程安全的

    为了使您的解决方案线程安全,您需要提供一种机制来防止代理数组在循环的事件分派运行时发生更改

    您的解决方案还需要维护类中的委托数组。使用NotificationCenter,您可以简单地使用默认的中心,而不需要在类中实现add/remove方法。相反,实例可以注册自己以接收它们认为最合适的通知(选择器/块、队列、源)。您的源类不必担心这些细节。它只需要将自身注册为指定类型的通知源。使用块处理通知非常方便

    通知中心的另一种选择是使用键值,如果它满足用例的需要


    最终,您决定使用的机制取决于它如何最好地应用于您的特定用例。

    您不希望将NSNotificationCenter用于系统范围事件以外的任何事情(例如键盘外观或某些类似事件)。原因是它完全不是类型安全的,可以使所有内容都依赖于所有内容,并且不再得到编译时检查或使用情况搜索结果

    在我看来,KVO不应该被用来观察您正在收听的sinc对象之外的变化
    BM_LISTENER_METHOD_DECLARATION(protocol)
    BM_LISTENER_METHOD_IMPLEMENTATION(protocol)