3个Block替换Delegate的场景
Delegate定义
#import <Foundation/Foundation.h> @class ZYNetworkFetcher; @protocol ZYNetworkFetcherDelegate <NSObject> -(void)networkFetcher:(ZYNetworkFetcher *)networkfetcher didfinishWithData:(NSData *)data; @end @interface ZYNetworkFetcher : NSObject @property (nonatomic,weak) id< ZYNetworkFetcherDelegate> delegate; -(instance)initWithURL:(NSURL *)url; -(void)start; @end
Block定义
#import <Foundation/Foundation.h> typedef void(^ZYNetworkFetcherCompletionHandle01)(NSData *data); typedef void(^ZYNetworkFetcherCompletionHandle02)(NSData *data, NSError *error); @interface ZYNetworkFetcher : NSObject -(instance)initWithURL:(NSURL *)url; -(void)startWithCompletionHandle1:(ZYNetworkFetcherCompletionHandle01)handle; -(void)startWithCompletionHandle2:(ZYNetworkFetcherCompletionHandle02)handle; @end
场景一
在一个UIViewController中,存在2个UITable,那么在protocol的方法实现中,需要通过if/else区分是哪一个table,代码就被拉得很长,如果用block替代方案,某个table直接在API方法中传入对应的block即可。
好处:使用block块调用更方便,代码更清晰且API更紧致,block中还能捕获变量,
-(void)startMain { NSURL *url01 = [[NSURL alloc] initWithString:@"https://www.baidu.com"]; _obj01 = [[ZYNetworkFetcher alloc] initWithURL:url01]; _obj01.delegate = self; [_obj01 start]; NSURL *url02 = [[NSURL alloc] initWithString:@"https://www.google.com"]; _obj02 = [[ZYNetworkFetcher alloc] initWithURL:url02]; _obj02.delegate = self; [_obj02 start]; } -(void)networkFetcher:(ZYNetworkFetcher *)networkfetcher didfinishWithData:(NSData *)data { // 需要判断是哪一个对象的回调 if (networkfetcher == _obj01) { _objData01 = data; } else if(networkfetcher == _obj02){ _objData02 = data; } }
-(void)startMain { NSURL *url01 = [[NSURL alloc] initWithString:@"https://www.baidu.com"]; _obj01 = [[ZYNetworkFetcher alloc] initWithURL:url01]; [_obj01 startWithCompletionHandle1:^(NSData *data){ _objData01 = data; }]; NSURL *url02 = [[NSURL alloc] initWithString:@"https://www.google.com"]; _obj02 = [[ZYNetworkFetcher alloc] initWithURL:url02]; [_obj02 startWithCompletionHandle1:^(NSData *data){ _objData02 = data; }]; }
场景二
网络请求响应有成功和失败两种结果,一个block就能完成对成功和失败结果的处理。
有考虑用2个block分别处理,但这样不是最优。比如在处理响应成功的过程中发现错误,就得用失败的block处理,这时就会有重复性代码。
-(void)startMain { NSURL *url01 = [[NSURL alloc] initWithString:@"https://www.baidu.com"]; _obj01 = [[ZYNetworkFetcher alloc] initWithURL:url01]; [_obj01 startWithCompletionHandle2:^(NSData *data, NSError *error){ if (error) { // ...... } else { // ...... } }]; NSURL *url02 = [[NSURL alloc] initWithString:@"https://www.google.com"]; _obj02 = [[ZYNetworkFetcher alloc] initWithURL:url02]; [_obj02 startWithCompletionHandle2:^(NSData *data, NSError *error){ if (error) { // ...... } else { // ...... } }]; }
场景三
在API中,添加queue参数,可以将block回调任务提交到指定的queue。
好处:方便调用者对block的调度