通知、代理和协议之间有什么区别?

3
什么是协议或委托与NSNotification之间的区别?什么是“观察者”,它是如何工作的?
2个回答

30

协议

文档:协议

协议是定义对象响应某些方法的接口。关键在于,任何类都可以采用这些协议,以确保对象响应这些方法。

如果声明了一个协议:

@protocol Photosynthesis
@required
- (void)makeFood:(id<Light>)lightSource;
@optional
+ (NSColor *)color; // usually green
@end

那么你可以从其他不一定直接相关的类中继承它:

@interface Plant : Eukaryote <Photosynthesis>
// plant methods...
@end
@implementation Plant
// now we must implement -makeFood:, and we may implement +color
@end
或者
@interface Cyanobacterium : Bacterium <Photosynthesis>
// cyanobacterium methods...
@end
@implementation Cyanobacterium
// now we must implement -makeFood:, and we may implement +color
@end

现在,如果我们只关心符合协议,那么我们可以任意交替使用这些类:

id<Photosynthesis> thing = getPhotoautotroph(); // can return any object, as long as it conforms to the Photosynthesis protocol
[thing makeFood:[[Planet currentPlanet] sun]]; // this is now legal

委托和通知

文档:Cocoa设计模式

这是两种在对象之间传递消息的方法。主要区别:

  • 使用委托,一个指定的对象接收消息。
  • 当发布通知时,任意数量的对象可以接收到通知。

通常使用协议来实现委托:一个类通常会有类似于以下的内容:

@property (weak) id<MyCustomDelegate> delegate;

这会给委托一定的方法需要实现。你可以使用

myObject.delegate = /* some object conforming to MyCustomDelegate */;

然后对象可以向其委托发送相关消息。一个常见的例子是查看UITableViewDelegate协议

另一方面,通知是使用NSNotificationCenter实现的。一个对象(或多个对象)只需将自己添加为特定通知的观察者,当它们被另一个对象发布时,就可以接收到这些通知。

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(notificationHappened:)
                                             name:MyCustomNotificationName
                                           object:nil];

然后只需实现即可。

- (void)notificationHappened:(NSNotification *)notification {
    // do work here
}

您可以使用任何地方的代码发布通知:

[[NSNotificationCenter defaultCenter] postNotificationName:MyCustomNotificationName
                                                    object:self
                                                  userInfo:nil];

一定要确保在完成时调用removeObserver:


4
请提供简化版的完整文档和简单示例。非常感谢。喜欢光合作用的例子。 - danneu
这种情况下,可以改善推荐哪种方法来通过一系列嵌套的类传递消息,同时仍然允许松耦合。仅仅说明代理是什么,或者通知是什么,并不能真正帮助决定在特定场景中使用哪种方法。 - Logicsaurus Rex

5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接