美文网首页iOS程序猿iOS开发记录iOS学习笔记
block与delegate在代码组织上的特点

block与delegate在代码组织上的特点

作者: Lol刀妹 | 来源:发表于2019-02-25 23:05 被阅读4次

    代码组织是影响代码可读性的重要因素之一,block与delegate对代码的组织提供了两个不同的方向:

    • block:让代码更集中
    • delegate:让代码更有层次

    举例说明:

    我封装了一个倒计时button,提供了block与delegate两种回调方式:

    • block
    __weak typeof(self) weakSelf = self;
    
    [self.countDownButton configDuration:10 buttonClicked:^{
        //========== 按钮点击 ==========//
        [weakSelf.countDownButton startCountDown];
    } countDownStart:^{
        //========== 倒计时开始 ==========//
        NSLog(@"倒计时开始");
    } countDownUnderway:^(NSInteger restCountDownNum) {
        //========== 倒计时进行中 ==========//
        NSString *title = [NSString stringWithFormat:@"%ld秒后重试", restCountDownNum];
        [weakSelf.countDownButton setTitle:title forState:UIControlStateNormal];
    } countDownCompletion:^{
        //========== 倒计时结束 ==========//
        [weakSelf.countDownButton setTitle:@"点击获取验证码" forState:UIControlStateNormal];
        NSLog(@"倒计时结束");
    }];
    
    • delegate
    self.countDownButton.dataSource = self;
    self.countDownButton.delegate = self;
    
    #pragma mark - CQCountDownButton DataSource
    
    // 设置倒计时总时间
    - (NSInteger)startCountDownNumOfCountDownButton:(CQCountDownButton *)countDownButton {
        return 10;
    }
    
    #pragma mark - CQCountDownButton Delegate
    
    // 倒计时按钮点击时回调
    - (void)countDownButtonDidClick:(CQCountDownButton *)countDownButton {
        [self.countDownButton startCountDown];
    }
    
    // 倒计时开始的回调
    - (void)countDownButtonDidStartCountDown:(CQCountDownButton *)countDownButton {
        NSLog(@"倒计时开始");
    }
    
    // 倒计时进行中的回调
    - (void)countDownButtonDidCountDown:(CQCountDownButton *)countDownButton withRestCountDownNum:(NSInteger)restCountDownNum {
        NSString *title = [NSString stringWithFormat:@"%ld秒后重试", restCountDownNum];
        [self.countDownButton setTitle:title forState:UIControlStateNormal];
    }
    
    // 倒计时结束时的回调
    - (void)countDownButtonDidEndCountDown:(CQCountDownButton *)countDownButton {
        [self.countDownButton setTitle:@"点击获取验证码" forState:UIControlStateNormal];
        NSLog(@"倒计时结束");
    }
    

    可以看到,采用block的方式,可以将几个回调集中在一个方法里,而delegate,每个回调都需要一个代理方法。

    似乎看来,从代码组织层面上讲,block比delegate要好很多。

    如果你这样想就真的太年轻了。delegate的特点是让代码组织更有层次,只有当代码量比较大的时候才能体现出分层的优势。比如,还是拿这个倒计时按钮举例,现在增加一个需求:点击按钮时先获取验证码,获取成功后再开始倒计时。

    • 现在block里的代码是这样的:
    __weak typeof(self) weakSelf = self;
    [self.countDownButton configDuration:10 buttonClicked:^{
        //========== 按钮点击 ==========//
        [SVProgressHUD showWithStatus:@"正在获取验证码..."];
        // 模拟数据请求
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            int a = arc4random() % 2;
            if (a == 0) {
                // 获取成功
                [SVProgressHUD showSuccessWithStatus:@"验证码已发送"];
                // 获取到验证码后开始倒计时
                [weakSelf.countDownButton startCountDown];
            } else {
                // 获取失败
                [SVProgressHUD showErrorWithStatus:@"获取失败,请重试"];
                [weakSelf.countDownButton endCountDown];
            }
        });
    } countDownStart:^{
        //========== 倒计时开始 ==========//
        NSLog(@"倒计时开始");
    } countDownUnderway:^(NSInteger restCountDownNum) {
        //========== 倒计时进行中 ==========//
        NSString *title = [NSString stringWithFormat:@"%ld秒后重试", restCountDownNum];
        [weakSelf.countDownButton setTitle:title forState:UIControlStateNormal];
    } countDownCompletion:^{
        //========== 倒计时结束 ==========//
        [weakSelf.countDownButton setTitle:@"点击获取验证码" forState:UIControlStateNormal];
        NSLog(@"倒计时结束");
    }];
    

    是不是感觉多了一大坨代码瞬间可读性就降低了很多?如果每个block里都是一大坨代码呢?你或许会说老子把那坨代码抽离出去弄个新方法不就OK了?当然OK,不过这个时候你去看看delegate,用它来处理是不是好看多了?

    总结

    当代码量比较小且将多个回调聚集在一起可读性较高时,block是不错的选择;
    当代码量比较大且需要较好的区分各个回调时,delegate是很好的选择。

    相关文章

      网友评论

        本文标题:block与delegate在代码组织上的特点

        本文链接:https://www.haomeiwen.com/subject/wazvyqtx.html