《Effective Objective-C 2.0 》 阅读笔

2016-03-25  本文已影响71人  dibadalu

第23条:通过委托与数据源协议进行对象间通信

1. 委托模式

对象之间经常需要相互通信,在iOS中通信有委托Block两种方式。委托模式(Delegate pattern)定义一套接口,某对象若想接受另一个对象的委托,则需遵从此接口,以便成为其“委托对象”(delegate)。而这“另一个对象”则可以给其委托对象回传一些信息,也可以在发生相关事件时通知委托对象。此模式可将数据与业务逻辑解耦。

2. 例子

Snip20160325_9.png

EOCNetworkFetcher类

/* EOCNetworkFetcher头文件 */
#import <Foundation/Foundation.h>

@class EOCNetworkFetcher;
// 委托协议
@protocol EOCNetworkFetcherDelegate
@optional
- (void)networkFetcher:(EOCNetworkFetcher*)fetcher didReceiveData:(NSData*)data;
- (void)networkFetcher:(EOCNetworkFetcher*)fetcher didFailWithError:(NSError*)error;
- (void)networkFetcher:(EOCNetworkFetcher*)fetcher didUpdateProgressTo:(float)progress;
@end

@interface EOCNetworkFetcher : NSObject

@property(nonatomic ,weak) id<EOCNetworkFetcherDelegate> delegate; // 用来存放委托对象的属性

@end

/* EOCNetworkFetcher实现文件 */
#import "EOCNetworkFetcher.h"

@interface EOCNetworkFetcher (){
    struct { // 含有位段的结构体,用来缓存“委托对象是否能响应相应协议方法”这一信息
        unsigned int didReceiveData      : 1;
        unsigned int didFailWithError    : 1;
        unsigned int didUpdateProgressTo : 1;
    }_delegateFlags;
}
@end

@implementation EOCNetworkFetcher
// 覆写delegate的setter方法
- (void)setDelegate:(id<EOCNetworkFetcherDelegate>)delegate
{
    _delegate = delegate;
    _delegateFlags.didReceiveData = [_delegate respondsToSelector:@selector(networkFetcher:didReceiveData:)];
    _delegateFlags.didFailWithError = [_delegate respondsToSelector:@selector(networkFetcher:didFailWithError:)];
    _delegateFlags.didUpdateProgressTo = [_delegate respondsToSelector:@selector(networkFetcher:didUpdateProgressTo:)];
}

// 伪方法,从网络获取数据
- (void)dataFromNetwork 
{
    NSData *data = /* data obtained from network */;
    if (_delegateFlags.didReceiveData) {
        [_delegate networkFetcher:self didReceiveData:data];
    }
}

@end

EOCDataModel类

/* EOCDataModel实现文件 */
#import "EOCDataModel.h"
#import "EOCNetworkFetcher.h"

@interface EOCDataModel () <EOCNetworkFetcherDelegate> // 遵守**协议
@end

@implementation EOCDataModel

#pragma mark - EOCNetworkFetcherDelegate
- (void)networkFetcher:(EOCNetworkFetcher *)fetcher didReceiveData:(NSData *)data
{
    /* handle data */
}

- (void)networkFetcher:(EOCNetworkFetcher *)fetcher didFailWithError:(NSError *)error
{
    /* handle error */
}
@end

3. 注意点

Snip20160325_10.png

要点

上一篇下一篇

猜你喜欢

热点阅读