ReactiveCocoa源码拆分解析(五)
(整个关于ReactiveCocoa的代码工程可以在https://github.com/qianhongqiang/QHQReactive下载)
好多天没写东西了,今天继续。主要讲解RAC如何于UI空间实现响应流的。
随手找个按钮响应的RAC实现作为示例,然后我们去做一个简单的实现
[[_HiddenBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
_HiddenBtn.hidden = YES;
}];
我把一些别的逻辑全部删除,大家也不要关注任何内存问题。这个示例的功能很简单,就是一个按钮被点击抬起这个事件触发后,按钮隐藏。嗯,实现的非常优雅,逻辑也整合到一块去了,代码清晰明了。
我们实现的思路是这样的,创建一个信号,将这个信号与按钮关联,每次触发点击的时候,将值传递给这个信号,沿着信号管道去传递给订阅者。
-(QHQSignal *)qhq_signalForControlEvents:(UIControlEvents)event;我们添加一个UIControl分类,添加类似的方法。
然后考虑一下正常情况下按钮的响应通常是如何添加的,没错,很常见的
[按钮 addTarget:目标对象 action:目标对象方法 forControlEvents:响应事件];
来看看创建信号的方法
+(QHQSignal *)createSignal:(void(^)(id subscriber))didSubscriber
我们之前一直是让这个匿名内建的subscriber去发送消息,比如sendNext等事件,所以顺着这个思路,只需要把addTarget的目标添加为这个subscriber,调用subscriber的sendNext方法就可以了。然后我们来实现一下
-(QHQSignal *)qhq_signalForControlEvents:(UIControlEvents)event {
return [QHQSignal createSignal:^(id<QHQSubscrib> subscriber) {
[self addTarget:subscriber action:@selector(sendNext:) forControlEvents:event];
}];
}
是的,就这一句话就行了。然后来测试以下,我们创建个按钮,然后点击后输出些什么
[[demoButton qhq_signalForControlEvents:UIControlEventTouchDown] subscribeNext:^(id x) {
NSLog(@"%@---被点击了",x);
}];}
结果我点了半天,发现屏幕没有任何输出,怎么回事呢?然后我就开始调试,沿着整个栈信息找,没有什么问题,该创建的都创建了,可以是subscriber的sendNext方法不调用。我重写了一下subscriber的dealloc方法,插了一个断点,预料的一样,进断点了,也就是subscriber被干掉了。
我马上去翻了下API文档,展示一下
// passing in nil as the target goes up the responder chain. The action may optionally include the sender and the event in that order
// the action cannot be NULL. Note that the target is not retained.
- (void)addTarget:(nullable id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;
赫然写着Note that the target is not retained.后来想想,这也是必然的,不然按照常规写法,那不都跟VC循环引用了,自己小白了。
实际上,在RAC中对生命周期的管理做的还是很到位,这里暂时不展开,涉及到的东西比较多。以学习目的为主,我暂时将这个subscriber进行一次retain。
-(QHQSignal *)qhq_signalForControlEvents:(UIControlEvents)event {
return [QHQSignal createSignal:^(id<QHQSubscrib> subscriber) {
[self addTarget:subscriber action:@selector(sendNext:) forControlEvents:event];
objc_setAssociatedObject(self, _cmd, subscriber, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}];
}
这样代码可以正常运行了。
2016-01-07 13:50:43.142 PageText[10115:8236159] <UIButton: 0x7ff30a771730; frame = (0 200; 320 40); opaque = NO; layer = <CALayer: 0x7ff30a70c930>>---被点击了
在这处理中,自己也是长进不少。剩余的控件大家可以顺着这个思路自己摸索。
ReactiveCocoa源码拆分解析(五)的更多相关文章
- ReactiveCocoa源码拆分解析(一)
(整个关于ReactiveCocoa的工程可以在https://github.com/qianhongqiang/QHQReactive下载) ReactiveCocoa的介绍我就不说了,可以自行百度 ...
- ReactiveCocoa源码拆分解析(二)
(整个关于ReactiveCocoa的代码工程可以在https://github.com/qianhongqiang/QHQReactive下载) 上面抽丝剥茧的把最主要的信号机制给分离开了.但在RA ...
- ReactiveCocoa源码拆分解析(四)
(整个关于ReactiveCocoa的代码工程可以在https://github.com/qianhongqiang/QHQReactive下载) 上一章节简要的说明了如何实现的热信号.但是像那么写, ...
- ReactiveCocoa源码拆分解析(七)
(整个关于ReactiveCocoa的代码工程可以在https://github.com/qianhongqiang/QHQReactive下载) 在这篇博客中,我将把ReactiveCocoa中的擦 ...
- ReactiveCocoa源码拆分解析(六)
(整个关于ReactiveCocoa的代码工程可以在https://github.com/qianhongqiang/QHQReactive下载) RAC为了实现优雅的信号绑定,可谓使尽浑身解数,不仅 ...
- ReactiveCocoa源码拆分解析(三)
(整个关于ReactiveCocoa的代码工程可以在https://github.com/qianhongqiang/QHQReactive下载) 这一章节主要讨论信号的“冷”与“热” 在RAC的世界 ...
- 并发编程(十五)——定时器 ScheduledThreadPoolExecutor 实现原理与源码深度解析
在上一篇线程池的文章<并发编程(十一)—— Java 线程池 实现原理与源码深度解析(一)>中从ThreadPoolExecutor源码分析了其运行机制.限于篇幅,留下了Scheduled ...
- Spring框架之spring-web web源码完全解析
Spring框架之spring-web web源码完全解析 spring-web是Spring webMVC的基础,由http.remoting.web三部分组成,核心为web模块.http模块封装了 ...
- 【原】AFNetworking源码阅读(五)
[原]AFNetworking源码阅读(五) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中提及到了Multipart Request的构建方法- [AFHTTP ...
随机推荐
- BZOJ 2330: [SCOI2011]糖果 [差分约束系统] 【学习笔记】
2330: [SCOI2011]糖果 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 5395 Solved: 1750[Submit][Status ...
- JSON 字符串中的中括号和大括号区别详解
json 变量有两种可能, 可能是一个对象, (类似 类的实例), 也可能是一个数组!! 主要是要 从 ""语义" 上来分析, 到底该用 大括号还是用中括号: 如果从语义 ...
- 掌握SortSet接口和Set接口的关系,以及常用方法。
TreeSet类是可以排序的类.TreeSet实际上也是SortSet接口的子类. 此接口的所有类都是可以排序的. 所有的方法: 实例: package 类集; import java.util.So ...
- C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本 - 数据权限增强、范围权限增强
并不是不想做B\S的管理工具,只是精力实在不够,由于用户权限管理组件是基础组件.所以C\S的也无妨,不会有几个人在乎Oracle,SQLServer是否不b\s的,注重的是功能性能,请大家不要纠结与是 ...
- How to create a launcher for a manually extracted program in Ubuntu
Say we have a latest Blender extracted from the download package. We want to create a launcher for B ...
- ReactNative新手学习之路01-创建项目开始
新手学习之路01-创建项目开始 小菜鸟准备学习RN开发,决定写下自己的学习历程,方便其他也想要学习RN的人,后期会持续更新写下自己所有学习经历,一步步从菜鸟成长成业内高手.开发环境准备,本文默认环境已 ...
- 深入理解Java:注解
注解作用:每当你创建描述符性质的类或者接口时,一旦其中包含重复性的工作,就可以考虑使用注解来简化与自动化该过程. Java提供了四种元注解,专门负责新注解的创建工作. 元注解 元注解的作用就是负责注解 ...
- knockoutJS学习笔记09:使用mapping插件
一.问题引出 通常,我们先定义好html结构或者模板,通过ajax向后台发起请求,后台返回json数据,然后再将json数据渲染到页面上.以博客园个人博客里的个人信息为例子,如图: 1.定义html. ...
- 学python
1.*和** def sum(*x): ans=0 for i in x: ans+=i return ans def haha(one,two): print(one,' ',two) print( ...
- webpack ---loader,plugin下载命令
css-loader: cnpm install style-loader css-loader url-loader babel-loader sass-loader file-loader -- ...