高效编写代码的方法(十九):Delegate要点

2016-06-30  本文已影响240人  蜂猴

在OC中有很多方式可以进行对象间的“通信”,其中一种方式就是通过设置代理。
OC中使用代理的方式就不做过多介绍了。
重点介绍下使用代理需要注意或者可以提高的地方。

引用循环

可以参照官方的代理写法:

@property (nonatomic, weak, nullable) id <UITableViewDataSource> dataSource;
@property (nonatomic, weak, nullable) id <UITableViewDelegate> delegate;

注意属性的修饰符是weak而不是strong,表示代理与委托之间的关系:
代理或者别的对象可能持有委托,而委托不持有代理。
声明为weak以防止引用循环。

内省判断

在真正执行代理方法之前,先判断delegate能否执行协议中声明的方法,一般如下判断:

if ([_delegate respondToSelector:@selector(someMethod:)]){
        [_delegate someMethod:data];
}

这样判断的好处就是在于即时delegate没有实现方法,当delegate被触发想要执行时,也不会因为找不到方法而造成程序崩溃。

命名与参数

协议的方法命名除了要准确传达方法的意思(OC的传统)之外最好还能将所代理的对象作为参数写入命名中,比如一个数据加载器的协议方法:

- (void)networkFetcher:(NetworkFetcher *)fetcher
        didReceiveData:(NSData *)data;

这样的好处在于delegate在执行的时候可以判断出不同的委托对象从而执行不同的方法:

- (void)networkFetcher:(NetworkFetcher *)fetcher
        didReceiveData:(NSData *)data{
      if(fetcher == _fetcherA){
        //do A
      }else{
        //do B
}

定向

举个例子,应该就非常好理解了。

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType

以上是一个WebView的原生代理,可以用来决定是否能发起某些特定的请求。

我们自己也可以多使用类似的代理方法进行某些定向问题的判断。

提供数据源

有时候,我们不止希望delegate能处理一些回调的逻辑,还希望delegate能给我们的委托对象提供一些数据源。此时我们就可以使用名为“dataSource”(自己命名也可以)的代理来处理数据部分的问题。最经常使用的就是在tableview中,我们使用dataSource来提供cell的数量以及cell。

使用delegate与dataSource分开的方式可以将逻辑与数据分开进行处理,显得比较清晰。

快速内省

一旦我们协议中有很多的代理方法时候,为了安全,我们每次执行都去进行一次respondToSelector的内省判断,那么整个过程就需要不断地重复写判断,显得非常麻烦。

有一种简单的方法就是定义一个结构体,然后用该结构体来保存所有的内省判断的结果。
举个例子:

@interface NetworkFetcher(){
struct {
    unsigned int didReceiveData :1;
    unsigned int didFailWithError:1;
    unsigned int didUpdateProgress:1;
    }_delegateFlag;
    }
}

以上结构体_delegateFlag就以三个1字节的数据用来保存是否响应代理方法的Bool值。
在setDelegate:方法中我们进行统一判断和保存 ,如下:

- (void)setDelegate:(id<NetworkFetcher>)delegate{
    _delegate = delegate;
    _delegateFlag.didReceiveData = [_delegate respondToSelector:@selector(networFetcher:didReceiveData:)];
    //省略
}

这样一来,在后续的判断中,我们可以直接使用_delegateFlag来判断代理能否响应方法。

上一篇下一篇

猜你喜欢

热点阅读