(整个关于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源码拆分解析(五)的更多相关文章

  1. ReactiveCocoa源码拆分解析(一)

    (整个关于ReactiveCocoa的工程可以在https://github.com/qianhongqiang/QHQReactive下载) ReactiveCocoa的介绍我就不说了,可以自行百度 ...

  2. ReactiveCocoa源码拆分解析(二)

    (整个关于ReactiveCocoa的代码工程可以在https://github.com/qianhongqiang/QHQReactive下载) 上面抽丝剥茧的把最主要的信号机制给分离开了.但在RA ...

  3. ReactiveCocoa源码拆分解析(四)

    (整个关于ReactiveCocoa的代码工程可以在https://github.com/qianhongqiang/QHQReactive下载) 上一章节简要的说明了如何实现的热信号.但是像那么写, ...

  4. ReactiveCocoa源码拆分解析(七)

    (整个关于ReactiveCocoa的代码工程可以在https://github.com/qianhongqiang/QHQReactive下载) 在这篇博客中,我将把ReactiveCocoa中的擦 ...

  5. ReactiveCocoa源码拆分解析(六)

    (整个关于ReactiveCocoa的代码工程可以在https://github.com/qianhongqiang/QHQReactive下载) RAC为了实现优雅的信号绑定,可谓使尽浑身解数,不仅 ...

  6. ReactiveCocoa源码拆分解析(三)

    (整个关于ReactiveCocoa的代码工程可以在https://github.com/qianhongqiang/QHQReactive下载) 这一章节主要讨论信号的“冷”与“热” 在RAC的世界 ...

  7. 并发编程(十五)——定时器 ScheduledThreadPoolExecutor 实现原理与源码深度解析

    在上一篇线程池的文章<并发编程(十一)—— Java 线程池 实现原理与源码深度解析(一)>中从ThreadPoolExecutor源码分析了其运行机制.限于篇幅,留下了Scheduled ...

  8. Spring框架之spring-web web源码完全解析

    Spring框架之spring-web web源码完全解析 spring-web是Spring webMVC的基础,由http.remoting.web三部分组成,核心为web模块.http模块封装了 ...

  9. 【原】AFNetworking源码阅读(五)

    [原]AFNetworking源码阅读(五) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中提及到了Multipart Request的构建方法- [AFHTTP ...

随机推荐

  1. cf之路,1,Codeforces Round #345 (Div. 2)

     cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅.....   ...

  2. NYOJ 105

    九的余数 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 现在给你一个自然数n,它的位数小于等于一百万,现在你要做的就是求出这个数整除九之后的余数. 输入 第一行有一个整 ...

  3. TortoiseSVN 中 一个 Merge revisions to.. 小坑

    注意: 不能只选头与尾svn号, 一定要全选 !!全选 !!全选 !!

  4. 【转】【C#】迭代器

    迭代器模式是设计模式中行为模式(behavioral pattern)的一个例子,他是一种简化对象间通讯的模式,也是一种非常容易理解和使用的模式.简单来说,迭代器模式使得你能够获取到序列中的所有元素而 ...

  5. Python-09-paramiko模块

    开发堡垒机之前,先来学习一下Python的paramiko模块,该模块基于SSH用于连接远程服务器并执行相关操作. SSHClient 用于连接远程服务器并执行基本命令 基于用户名密码连接 impor ...

  6. 以moosefs为例介绍iozone的使用方法

    一.编译安装 首先到官网下载iozone的稳定版源码 http://www.iozone.org/ 然后解压编译 tar -vxf iozone3_458.tar cd iozone3_458/src ...

  7. 云计算之路-阿里云上:13:43-13:44之间RDS故障影响了全站的正常访问

    抱歉!13:43-13:44之间,由于阿里云RDS(云数据库)出现2分钟突发故障,影响了全站的正常访问,给大家带来了麻烦,望大家谅解! 故障期间,应用程序日志中记录的错误信息如下: System.Da ...

  8. Android ORM 框架之 greenDAO 使用心得

    前言 我相信,在平时的开发过程中,大家一定会或多或少地接触到 SQLite.然而在使用它时,我们往往需要做许多额外的工作,像编写 SQL 语句与解析查询结果等.所以,适用于 Android 的ORM  ...

  9. url参数中带有+号,服务器端解码之后没了

    解决办法: 客户端:encodeURIComponent 服务器端:Uri.UnescapeDataString 参考网址:http://www.cnblogs.com/artwl/archive/2 ...

  10. CSS div水平垂直居中和div置于底部

    一.水平居中 .hor_center { margin: 0 auto; } 二.水平垂直居中 .content { width: 360px; height: 240px; } .ver_hor_c ...