运行时编程block
来源:互联网 发布:韩顺平php入门到精通 编辑:程序博客网 时间:2024/06/09 17:04
CallBack-回调,在各个编程语言中都是很重要的一个功能,比如弹窗一个子控件,在子控件中获取到信息后需要返回数据给调用方,最主流的做法就是把调用方作为参数传到子控件中,然后当子控件拿到信息以后再把信息传递给之前进来的调用方。在iOS中,是通过一种叫delegate(代理)的方式来实现,通常在创建子控件的时候会看到一句:子控件.delegate = self, 意思是说,我就是这个子控件的代理,当子控件需要回调的时候,就直接调用其成员delegate(也就是我), 就可以把信息传递回去。
然而在很多情况下这样的代理会显得很‘啰嗦’,比如我只是想简单的弹出一个对话框(UIAlertView)然后知道用户选择的是Ok还是Cancel, 却要在调用方做两件事,首先是声明这个对话框的协议(protocol)用以具备接收对话框回调的资格,然后再去实现回调方法,比如OnOk, OnCancel,等等,更麻烦的是,如果我在此有三个对话框的话,就要实现多个协议,做他们的代理。
所以这里可以用Block对其闭包,直接在上下文的地方声明回调,不仅不用增加回调方法,而且很轻易的解决了多重回调的复杂局面。现在就拿UIAlertView举一个例子:
正常做法:调用方在召唤alertview的同时,将其代理指向自己:alertview.delegate = self; 然后在用户点击对话框上面的按钮的时候,触发其回调方法(如果它的代理存在的前提,如果没有声明指向的话不会被调用):
// Called when a button is clicked. The view will be automatically dismissed after this call returns
- (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;
这里的优化思路是:
修改UIAlertView这个类,增加一个block对象,然后让其自己做自己的delegate, 调用方将block作为参数传进去以后,在自己的clickedButtonAtIndex方法中调用block即可。
具体实现:
1. 创建UIAlertView的类扩展,UIAlertView+Block;
2. 声明回调Block:
typedefvoid (^UIAlertViewCompletionBlock) (UIAlertView *alertView,NSIntegerbuttonIndex);
3. 增加接口,将block传进来.
+ (instancetype)showWithTitle:(NSString *)title
message:(NSString *)message
style:(UIAlertViewStyle)style
cancelButtonTitle:(NSString *)cancelButtonTitle
otherButtonTitles:(NSArray *)otherButtonTitles
tapBlock:(UIAlertViewCompletionBlock)tapBlock;
4. 在设置tapBlock的时候,修改对象,新增成员变量,此处是核心:
objc_setAssociatedObject(self,UIAlertViewTapBlockKey, tapBlock,OBJC_ASSOCIATION_COPY);
*UIAlertViewTapBlockKey 不是字符串,是一个void*, 与tapBlock形成K-V唯一配对,向一个UIAlertView查key,就可以得到tapBlock作为value返回。 这里的setAssociatedObject是运行时编程中API,所以需要#import<objc/runtime.h>
此时,tapBlock就已被植入到对象UIAlertView中,同时可以用key-value的方式获取。
5.将代理指向自己
self.delegate = (id<UIAlertViewDelegate>)self;
6.实现代理方法- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex,在里面调用植入的tabBlock.
- 运行时编程block
- [iOS] #运行时编程# Block植入
- Block 编程
- Block编程
- 运行PL/SQL时只输出anonymous block completed
- IOS block编程注意事项
- IOS-Block编程
- IOS-Block编程
- IOS block编程注意事项
- IOS 之Block编程
- IOS block编程注意事项
- Objective- C 编程 Block
- 学会使用Block编程
- oc block链式编程
- Block的链式编程
- 编程技巧 - block
- 编程技巧 - 关联+Block
- 多线程编程之block
- 停止Eclipse LogCat的自动滚动
- 如何使用android系统自带资源
- 简易手电筒实现
- Android的事件处理1
- iClap是什么,能解决什么问题?
- 运行时编程block
- MySql大文件插入错误
- 《王保明老师----Linux开发学习笔记》------讲08:进程 -----多进程下的文件描述符
- 不同内核浏览器的差异以及浏览器渲染简介
- 每天一个linux命令(1):wget命令
- Linux目录规范和含义(整理)
- 字典树java版本
- [Cocoa]_[画直线、矩形、文字]
- systemctl命令用法