我们在自定义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的生命周期。
 
 
这个库的主要目的是简化自己平时常用的代码,所以并没有对各种事件各种控件封装的很完整,所以目前只有这几个分类,其他的等以后用到再慢慢加~
有什么问题,欢迎讨论~ 

用block做事件回调来简化代码,提高开发效率的更多相关文章

  1. tomcat免重启随意更改java代码 提高开发效率

    转载:http://developer.51cto.com/art/201012/241243.htm 做为了一个java开发人员,总是为因为要增加一个类,或是增加删除一个方法,甚至修改一个小处代码而 ...

  2. 代码块: 以冒号作为开始,用缩进来划分作用域,这个整体叫做代码块,python的代码块可以提升整体的整齐度,提高开发效率

    # ### 代码块: 以冒号作为开始,用缩进来划分作用域,这个整体叫做代码块 if 5 == 5: print(1) print(2) if True: print(3) print(4) if Fa ...

  3. iOS开发-代码片段(Code Snippets)提高开发效率

    简介 在 XCode4 引入了一个新特性,那就是“代码片段(Code Snippets)”.对于一些经常用到的代码,抽象成模板放到 Code Snippets 中,使用的时候就只需要键入快捷键就可以了 ...

  4. python3 监控代码变化 自动重启 提高开发效率

    #!/usr/bin/env python3 # -*- coding: utf-8 -*- __author__ = 'Michael Liao' import os, sys, time, sub ...

  5. 专门为小白准备的入门级mybatis-plus-generator代码自动生成器,提高开发效率。值得收藏

    引入依赖 <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-g ...

  6. 一些减少代码量、提高开发效率的利器(Java)

    Spring Boot mybatis-plus代码生成器和自带CRUD接口 lombok 库: Apache Commons & guava AOP Java8: stream & ...

  7. 提高php开发效率的9大代码片段

    在网站开发中,我们都期望能高效快速的进行程序开发,如果有能直接使用的代码片段,提高开发效率,那将是极好的.php开发福利来了,今天小编就将为大家分享9大超实用的.可节省大量开发时间的php代码片段. ...

  8. Qt 学习之路 2(19):事件的接受与忽略(当重写事件回调函数时,时刻注意是否需要通过调用父类的同名函数来确保原有实现仍能进行!有好几个例子。为什么要这么做?而不是自己去手动调用这两个函数呢?因为我们无法确认父类中的这个处理函数有没有额外的操作)

    版本: 2012-09-29 2013-04-23 更新有关accept()和ignore()函数的相关内容. 2013-12-02 增加有关accept()和ignore()函数的示例. 上一章我们 ...

  9. .NET 事件总线,简化项目、类库、线程、服务等之间的通信,代码更少,质量更好。‎

    Jaina .NET 事件总线,简化项目.类库.线程.服务等之间的通信,代码更少,质量更好.‎ 安装 Package Manager Install-Package Jaina .NET CLI do ...

随机推荐

  1. 基于Node.js实现一个小小的爬虫

    以前一直听说有爬虫这种东西,稍微看了看资料,貌似不是太复杂. 正好了解过node.js,那就基于它来个简单的爬虫. 1.本次爬虫目标: 从拉钩招聘网站中找出“前端开发”这一类岗位的信息,并作相应页面分 ...

  2. 多用多学之Java中的Set,List,Map

            很长时间以来一直代码中用的比较多的数据列表主要是List,而且都是ArrayList,感觉有这个玩意就够了.ArrayList是用于实现动态数组的包装工具类,这样写代码的时候就可以拉进 ...

  3. 利用HAProxy代理SQL Server的AlwaysOn辅助副本

    利用HAProxy代理SQL Server的AlwaysOn辅助副本 公司最近数据库升级到SQL Server2014 ,并部署了alwayson高可用集群 机房内有三套程序需要读取数据库 第一套:主 ...

  4. 【初码干货】在Window Server 2016中使用Web Deploy方式发布.NET Web应用的重新梳理

    在学习和工作的过程中,发现很多同事.朋友,在做.NET Web应用发布的时候,依然在走 生成-复制到服务器 这样的方式,稍微高级一点的,就是先发布到本地,再上传到服务器 这种方式不仅效率低下,而且不易 ...

  5. DBCP 配置备注

    <property name="initialSize" value="5"></property> <property name ...

  6. Dubbo学习小记

    前言 周一入职的新公司,到了公司第一件事自然是要熟悉新公司使用的各种技术,搭建本地的环境. 熟悉新公司技术的过程中,首先就是Maven,这个前面已经写过文章了,然后就是Dubbo----公司的服务都是 ...

  7. AngularJs2与AMD加载器(dojo requirejs)集成

    现在是西太平洋时间凌晨,这个问题我鼓捣了一天,都没时间学英语了,英语太差,相信第二天我也看不懂了,直接看结果就行. 核心原理就是require在AngularJs2编译过程中是关键字,而在浏览器里面运 ...

  8. Eclipse常用设置

    用惯了VS,再回过去用Eclipse真是一件痛苦的事.so,在这里记录下使用过程中的一些设置以做备忘. 1.代码自动提示 在我们忘记方法名或者想偷懒时,代码自动提示很管用.不过Eclipse默认是输入 ...

  9. linux 下压缩大批量文件

    find ./ -name '*衢州*' -type f -print| xargs zip /home/Eyuncloud/qz_20150211.zip

  10. [译]基于GPU的体渲染高级技术之raycasting算法

    [译]基于GPU的体渲染高级技术之raycasting算法 PS:我决定翻译一下<Advanced Illumination Techniques for GPU-Based Volume Ra ...