我们在自定义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. eclipse,myeclipse 误删文件,回滚历史文件操作

    昨天因为误操作把一个写了一上午的代码给删了,找到的这个,以前竟然还没发现有这个功能- -! 具体操作: 1.建立同路径同名的文件 2.文件上右键 --> Compare With --> ...

  2. 【深入浅出jQuery】源码浅析2--奇技淫巧

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  3. To Java程序员:切勿用普通for循环遍历LinkedList

    ArrayList与LinkedList的普通for循环遍历 对于大部分Java程序员朋友们来说,可能平时使用得最多的List就是ArrayList,对于ArrayList的遍历,一般用如下写法: p ...

  4. ASP.NET MVC防范CSRF最佳实践

    XSS与CSRF 哈哈,有点标题党,但我保证这篇文章跟别的不太一样. 我认为,网站安全的基础有三块: 防范中间人攻击 防范XSS 防范CSRF 注意,我讲的是基础,如果更高级点的话可以考虑防范机器人刷 ...

  5. HTML (超文本标记语言)

    <html> --开始标签 <head> 网页上的控制信息 <title>页面标题</title> </head> <body> ...

  6. WEB 基础知识(一)

    1. 系统架构 1.1 B/S系统架构 1.2 C/S系统架构 1.3 对比与区别 1.3.1 概述 C/S结构,即Client/Server(客户机/服务器)结构,是大家熟知的软件系统体系结构,通过 ...

  7. 关于js中的this之判断this

    this绑定规则的优先级顺序 new操作符绑定 > 显示绑定 > 隐式绑定 > 默认绑定   所以在判断函数在某个调用位置应用的是哪条规则,可以按下列这样的顺序   if(函数在ne ...

  8. 【PRINCE2是什么】PRINCE2认证之七大原则(7)

    我们先来回顾一下,PRINCE2七大原则分别是持续的业务验证,经验学习,角色与责任,按阶段管理,例外管理,关注产品,剪裁 第七个原则:根据项目环境剪裁 PRINCE2的价值在于它是一个通用的项目管理方 ...

  9. 使用Newtonsoft.Json.dll(JSON.NET)动态解析JSON、.net 的json的序列化与反序列化(一)

    在开发中,我非常喜欢动态语言和匿名对象带来的方便,JSON.NET具有动态序列化和反序列化任意JSON内容的能力,不必将它映射到具体的强类型对象,它可以处理不确定的类型(集合.字典.动态对象和匿名对象 ...

  10. SQLServer 数据库镜像+复制方案

    目标: 主机做了Mirror和Replication,当主机出现问题时,Replication和Mirror实现自动的故障转移(Mirror 和Replication都切换到备机,而当主机 重新启动后 ...