通过NSNotifications。好?坏? NBD?

时间:2016-10-24 19:04:20

标签: ios objective-c nsnotificationcenter

我正在考虑将NSNotification对象作为var传递给方法的后果。

似乎很难通过通知跟踪逻辑流程中发生的事情(没有一些很好的评论和方法/对象命名),因此将通知传递给另一个方法/ class / lib / project只会使它成为现实调试或智能地响应错误的乐趣更少。

但感觉就像是有可能存在很多隐藏陷阱的东西。

我知道还有很多人喜欢通知。

那么有没有人有一些关于将实际的NSNotification对象作为方法之间的var传递的优点/缺点/更好的做法?

为了清楚起见,这里有一些伪代码:

[[NSNotificationCenter defaultCenter] postNotificationName:kSuperImportantNotification object:self userInfo:soMetaDict];

......后面的代码:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(importantThingHappened:) name:kSuperImportantNotification object:nil];

......后面的代码:

- (void) importantThingHappened:(NSNotification *)notification {
    [respondingInterestedClass executeSomethingWith:notification];
}

...在“respondInterestedClass”中:

- (void)executeServicesDiscoveredBlock:(NSNotification *)notification {
    // ... do something with the NSNotificaiton object.
}

由于

2 个答案:

答案 0 :(得分:4)

这取决于你在做什么,通常这是什么时候使用:

  • 一对一关系和松耦合:委托
  • 一对一关系和紧密耦合:直接方法调用
  • 一对多关系和松耦合:通知
  • 一对多关系和紧密耦合: KVO

因此,您不应该将Notifications用于所有类型的通信,即使不需要,许多开发人员也会大量使用Notifications。

说到这一点,将通知对象传递给方法处理程序是完全没问题的,但是不要把它传递给其他地方。

答案 1 :(得分:2)

暂时不论如何以及何时使用通知,并完全专注于完全正确选择的短暂用途......

收到通知对象后,状态容器包含一些状态集,其格式对系统来说很方便。你可以通过将键/值对推入字典并将其作为userInfo传递给你,如果你想要的话,可以将任何你想要的东西塞进去,但它仍然是系统状态。

在一个设计良好的代码体系中,存在着难以克服的障碍,通过这些障碍可以很好地定义数据格式和封装的消息传递。例如,在模型 - 视图 - 控制器系统中,Model类不会成为UIView的子类或直接处理用户事件。

通知应该被视为相同。收到通知后,将其解包到您想要的任何内部和特定于您的架构表示中,然后传递

或者,考虑一下:

- (void) somethingChangedNotification:(NSNotification *)changed
{
    [myModelGoop applyChange:...];
}

@implementation MyModelLayer
- (void)applyChange:(....)change
{
}

在上面,您当然可以将通知对象传递到模型层。但这只是将系统特定的实现细节推送到您的模型中。

当您通过NSNotification触发没有的更改时会发生什么?您要么将您的更改封装到假的NSNotification实例中(因为发布通知可能会产生副作用,具体取决于观察者)或者您必须重构上述内容以不再在模型层中发出通知。

最好尽早摆脱对系统封装的依赖。

为此,NSNotification实例应从不传递出处理通知的方法。