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的调度

原文地址:https://www.cnblogs.com/zhouyi-ios/p/7064206.html