zoukankan      html  css  js  c++  java
  • 用block做事件回调来简化代码,提高开发效率

       我们在自定义view的时候,通常要考虑view的封装复用,所以如何把view的事件回调给Controller就是个需要好好考虑的问题,
    一般来说,可选的方式主要有target-action和delegate,以及这次要强烈推荐的block。
         target-action和delegate方式有个很不方便的地方,就是配置代码和action代码不在同一个地方,你肯定要多写一个selector方法或者delegate方法,这就带来一个问题,一旦代码比较长或者selector方法比较多,找起来就很不方便。把响应事件直接写在配置的地方才是理想的选择!而且实现这一理想选择的方式,就是用block来做事件回调~
         比如view上有个button,你需要把button的响应事件回调给controller,你应该怎么做呢?
    最麻烦的方式应该是用delegate,你要给view定义delegate协议,在controller中实现这个方法,而写了这么多代码,仅仅是为了响应button的事件(delegate方法还没办法跟设置view写到一起),太不划算了;
     
    能不能省了定义协议实现协议的步骤呢?
    能!用block就好了,给view添加一个block属性来做回调,在配置view的时候把事件用block传进去,然后设置button的相应事件就是去执行这个block,这样配置代码跟回调还能写一起,貌似很不错哦~~
    但是,给button添加一个事件,仅仅就是为了去执行一个block,这也是重复劳动啊;
    能不能把这步也优化了呢?
    能!直接用button的addTarget方法就行了嘛,addTarget方法不就是为了简化这种情况的嘛~但是这样又不能把配置代码跟相应事件写到一起了。。。
    能不能把这两种方式结合一下呢?
    能!用LXMBlockKit(https://github.com/Phelthas/LXMBlockKit)就可以了~
    LXMBlockKit 给UIButton封装了一个 - (void)addButtonCallback:(UIButton *sender) 方法,让button自己来做target,然后去响应事件,一举两得!!!
    不用敲重复的代码,只用去设置回调就好了!!!

    原来button事件的典型写法:

    [testButton addTarget:self action:@selector(handleButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; 
    
    - (void)handleButtonTapped:(UIButton *)sender {    
        NSLog(@"handleButtonTapped");        
    }
    
    
    

    使用Block的写法:

       [testButton addButtonCallback:^(UIButton *sender) {
            NSLog(@"handleButtonTapped");
       }];
    
    
    
    可以看出来还是省了很多代码的,而且事件的回调就写在button的配置处,不用来回找~~
     
    不过也有必须要注意的地方:
    block回调中,务必使用weakSelf!直接使用self必定会导致循环引用!!!
    block回调中,务必使用weakSelf!直接使用self必定会导致循环引用!!!
    block回调中,务必使用weakSelf!直接使用self必定会导致循环引用!!!
    重要的事情说三遍!!!
    view只要add到Controller上,就会被强引用,而block是被view强引用的,所以如果block中又引用了self,那就一定会循环引用。。。
    这个我找了N久也没找到怎么用代码去判断有没有在block中引用self,所以没办法提示,只能靠自觉。。。没办法,养成好习惯吧
     
    类似的实现方式还有UIBarButtonItem和UIGesture,都可以用这种方式大大简化代码~
     
    NSNotificationCenter也可以用类似的方式,并且可以实现自动removeObserver,具体的实现方式稍有不同,主要是利用了属性在对象释放的时候会dealloc的原理,
    具体参考大神 nicklockwood的FXNotifications(https://github.com/nicklockwood/FXNotifications),我基本是按自己的代码习惯重新敲了一遍。
    也可以参考facebook的KVOController(https://github.com/facebook/KVOController
    或者大神zwaldowski的BlocksKit(https://github.com/zwaldowski/BlocksKit
     
    2017年6月10更新
    添加了NSTimer的block API,使用方法与其他分类类似,也要使用weakSelf;
    而且,因为NSTimer被添加到runloop的时候,runloop会强引用timer的target,所以计算NSTimer释放掉了,target可能还没释放,
    所以必须手动调用 invalidate()方法;
    一般在viewController中,invalidate方法写在viewController的dealloc中是不行的,因为runloop强引用viewController的话会导致viewController的dealloc不会被调用;
    使用这个block的API的话,可以将invalidate方法写在dealloc中,因为target是自定义的一个类,不影响viewController的生命周期。
     
     
    这个库的主要目的是简化自己平时常用的代码,所以并没有对各种事件各种控件封装的很完整,所以目前只有这几个分类,其他的等以后用到再慢慢加~
    有什么问题,欢迎讨论~ 
  • 相关阅读:
    站立会议11(冲刺二)
    站立会议10(冲刺二)
    站立会议09(冲刺二)
    站立会议08(冲刺二)
    每日站立会议(一)
    四则运算--单元测试
    四则运算安卓版
    返回二维数组最大联通子数组的和
    团队项目成员和题目
    第五周学习进度
  • 原文地址:https://www.cnblogs.com/Phelthas/p/5759114.html
Copyright © 2011-2022 走看看