用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

这个库的主要目的是简化自己平时常用的代码,所以并没有对各种事件各种控件封装的很完整,所以目前只有这几个分类,其他的等以后用到再慢慢加~

有什么问题,欢迎讨论~

时间: 2024-10-16 12:17:54

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

【Butter Knife】依赖注入方式简化代码提高开发效率

Butter Knife是一款非常不错的开源框架,其目的是简化代码,提高项目的开发效率. 以往的开发我们经常需要用findViewById(R.xx.xxx);几乎没个页面都会涉及到,无论Activity还是Fragment甚至listView.GridView中的 Adapter.这些重复性的代码会让人觉得很枯燥,因为闭上眼都不会敲错的代码,每天重复几百遍是有点耗时,尽管有代码提示.而且可能会因为不同field的忘记书写而导致NullPoint空指针. 那么还是直接进入主题: 步骤: 第三方框

Visual Studio 实用扩展推荐   Visual Studio 拥有非常不错的可扩展性,在之前的文章中,我也给大家示范了如何进行编辑器的扩展(详见文末参考资源)。在本篇文章中,我将介绍几款非常实用的扩展,从而帮助我们提高开发效率。 C# outline   Visual Studio 默认的大纲方案只允许在方法级别及以上进行代码的折叠,无法对一个if、while的区块进行折叠

Visual Studio 实用扩展推荐 Visual Studio 拥有非常不错的可扩展性,在之前的文章中,我也给大家示范了如何进行编辑器的扩展(详见文末参考资源).在本篇文章中,我将介绍几款非常实用的扩展,从而帮助我们提高开发效率. C# outline Visual Studio 默认的大纲方案只允许在方法级别及以上进行代码的折叠,无法对一个if.while的区块进行折叠,而这款工具则正好弥补了这个问题. highlight all occurrences of selected word

知晓设计模式,框架,去提高开发效率,使代码简洁

转自:http://kb.cnblogs.com/page/516088/ http://kb.cnblogs.com/page/516088/ 知晓各种设计模式,框架,技术技巧只是事情的一方面,而知道何时该.何时不该应用他们才是更重要的问题.在不知道一种技巧方式如何能对系统的开发有帮助的情况下,这种模式方法极有可能成为一种开发的阻碍,而不是一种有益的帮助. 好代码是廉价的代码. 但是 … 设计模式毕竟是个好东西 … 不是吗? 当然,但它们好在哪里?它们能提供什么好处? 容易维护 产品更健壮 容

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

#!/usr/bin/env python3 # -*- coding: utf-8 -*- __author__ = 'Michael Liao' import os, sys, time, subprocess from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler def log(s): print('[Monitor] %s' % s) class MyFileS

swift里类方法和构造方法的使用来减少代码冗余提高开发效率

对于日常中重复性的可以抽取的实现尽量抽取 比如实现导航栏右侧 UIBarButtonItem的添加 如果使用 private func setupNavigateionBar(){ let btn = UIButton() btn.setImage(UIImage(named:"icon_shouye_off"), for: .normal) btn.sizeToFit() navigationItem.leftBarButtonItem = UIBarButtonItem(custo

致力于极致提高开发效率和代码质量之快捷键和TDD

点我,我知道你不喜欢看文档,直接上视频 百度网盘地址:http://pan.baidu.com/s/1kTFqMJt 毕竟才工作四个月,老鸟请轻拍==

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

Spring Boot mybatis-plus代码生成器和自带CRUD接口 lombok 库: Apache Commons & guava AOP Java8: stream & lambda 反射 日志取代debug IDEA:使用恰当的开发工具并熟悉.熟练使用其功能 单元测试:不必运行整个项目,减少项目运行时间(好处之一) JRebel(热部署工具) 原文地址:https://www.cnblogs.com/thinkam/p/10350424.html

Swoole 关于reload重启与回调函数中代码的重载

Swoole 的 Server 中可以通过 PHP 来执行 reload 很方便的热重载, 但也有很多限制 需要注意的是, 直接写在 server.php 即 你的服务器启动脚本文件中的PHP代码即便是写在 WorkerStart 的事件回调中的代码 reload 也不会重载的, 必须是通过加载另一个文件来执行这样 reload 才会有意义 下面是测试代码和结果说明: <?php /** * Author: ZHOUZ * Blog: http://blog.csdn.net/zhouzme *

使用aicp实现事件回调模式

相对于asio事件等待池aiop的reactor模式,基于proactor模式的事件回调池aicp封转的更加的上层. 在类unix系统上 底层是基于aiop的实现,在一个线程里面进行事件等待,然后分发所有事件,在worker中处理完后调用回调返回到上层. 并对不同系统的aiop支持力度,进行针对性优化. 如果aiop支持边缘触发(例如:epoll.kqueue),尽量启用边缘触发,以减少系统api的频繁调用. 使用sendfile对发送文件进行优化 针对linux系统,启用native file