Objective-C中大多使用“委托模式”来实现对象间的通信。
实现方式
定义一套接口(delegate文件本身),若某对象想接受另一个对象的委托,则需要遵从此接口,以便成为其“委托对象”。(太拗口了,直接看实例)
举例
假设要编写一个从网上获取数据的类,此类要从远程服务器获取数据。远程服务器可能很长时间才应答。在这种情况一般使用委托模式:获取网络数据的类含有一个“委托对象”,在获取完数据之后,它会回调这个委托对象。这其中一共涉及到三个文件:NYNNetworkFetcherDelegate,NYNNetworkFetcher,NYNDataModel,他们关系如下:
- NYNNetworkFetcherDelegate
两个需要相互通信的对象(NYNNetworkFetcher和NYNDataModel)之间需要遵从的接口。遵循了这个接口,这两个对象就可以相互通信了。
注意:delegate对象总应该把发起委托的实例也一并传入方法中如下面的代码所示,这样delegate对象在实现相关方法时,就能够根据传入的实例分别执行不同的代码了。
@protocol NYNNetworkFetcherDelegate
@optional
- (void)networkFetcher:(NYNNetworkFetcher *)fetcher didReceiveData:(NSData *)data;
//如果将上面的这行代码换成如下就非常的不好
//- (void)networkFetcherDidReceiveData:(NSData *)data;
- NYNNetworkFetcher
通过这行代码[self.delegate networkFetcher:self didReceiveData:data];
,调用delegate中的networkFetcher:didReceiveData:
方法,将需要传送的数据传入进去
@interface NYNNetworkFetcher : NSObject
@property (nonatomic, weak) id <NYNNetworkFetcherDelegate> delegate;
@end
如果要在委托对象中调用可选方法,首先要判断这个委托对象是否实现了相关的方法。
优点是不用担心因为哪个方法没有实现而导致程序出问题。
NSData *data = /*从network中获得的数据*/;
if ([self.delegate respondsToSelector: @selector(networkFetcher:fetcher didReceiveData:data)])
{
[self.delegate networkFetcher:self didReceiveData:data];
}
- NYNDataModel
NYNDataModel对象是NYNNetworkFetcher的委托对象。
实现委托中的方法,处理接收到的data。
首先需要在NYNDataModel.m
中设置代理
NYNNetworkFetcher *networkFetcher = [[NYNNetworkFetcher alloc] init];
networkFetcher.delegate = self;
然后具体实现delegate中的方法
@implementation NYNDataModel () <NYNNetworkFetcherDelegate>
@end
@implementation NYNDataModel
- (void)networkFetcher:(NYNNetworkFetcher *)fetcher didReceiveData:(NSData *)data
{
//处理data
}
总结
NYNDataModel想要获取服务器中的数据,让NYNNetworkFetcher去服务器中取。NYNNetworkFetcher从服务器中取回了数据,怎样传给NYNDataModel呢?
NYNDataModel和NYNNetworkFetcher共同遵从一个接口delegate。NYNNetworkFetcher调用delegate中的一个方法,将从服务器中获得的数据给delegate。NYNDataModel具体实现delegate中的方法,从delegae中获得NYNNetworkFetcher传入delegate的数据。