ReactiveCocoa源码拆分解析(六)
(整个关于ReactiveCocoa的代码工程可以在https://github.com/qianhongqiang/QHQReactive下载)
RAC为了实现优雅的信号绑定,可谓使尽浑身解数,不仅是这个,整个RAC中对宏的使用都很有学习价值。我这里简单简单的说明下,我们在实际开发中常用到的宏,有些宏我也没有研究的很透彻,就不班门弄斧了,大家可以参考下别的学习资料。
以下面的例子入手:
RAC(self.noneDataTipView,hidden) = [RACSignal combineLatest:@[bannerSignal,messageSignal] reduce:^id(NSArray *bannerArray, NSArray *messageList){
return @(bannerArray.count || messageList.count);
}];
要实现的功能很简单,就是在bannerSignal与messageSignal这两个信号传来的数组都不包含元素时,将没有内容的提示页面展示出来,当有数据之后,该页面隐藏。
我根据RAC的实现,写了一个简易版的绑定,供学习参考,RAC的实现又关联了许多其他的宏,看起来比较复杂。
QHQSubscriptingAssignmentTrampoline这个类将给我们进行绑定。
- (id)initWithTarget:(id)target;提供了一个初始化方法,需要设置一个绑定的对象,也就是绑定谁。(RAC中还有1个nilValue)
接下来我们就实现那个宏,也是见证奇迹的时刻。
#define QHQ(TARGET, KEYPATH) \
[[QHQSubscriptingAssignmentTrampoline alloc] initWithTarget:(TARGET)][KEYPATH]
什么鬼?这样就可以了?后面的[KEYPATH]是什么东西?
这其实利用了clang的新特性,允许你像访问字典一样,访问一个对象,但是!对,这是有条件的,你需要重载一个函数,可能大部分OC程序员们对重载不太了解,那么你需要自行百度一下了。
- (void)setObject:(QHQSignal *)signal forKeyedSubscript:(NSString *)keyPath;
上面的方法就是奇迹发生的地方,看看函数的命名,你也明白了,用[]这种角标的形式访问。
简单的实现了下内部(不过功能不太完整),大致思路如此
- (void)setObject:(QHQSignal *)signal forKeyedSubscript:(NSString *)keyPath {
[signal subscribeNext:^(id x) {
[self.target setValue:x forKey:keyPath];
}];
}
之后写个demo测试一下
QHQ(self.view,@"backgroundColor") = [QHQSignal createSignal:^QHQDispose *(id subscriber) {
[subscriber sendNext:[UIColor yellowColor]];
return nil;
}];
运行一下,颜色变了。RAC为了实现这一优雅的绑定,可谓付出颇多心思,对github的开发者们致敬。
补充一下RACKVOChannel这个类的宏,也是这样实现的。
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如何于UI ...
- ReactiveCocoa源码拆分解析(三)
(整个关于ReactiveCocoa的代码工程可以在https://github.com/qianhongqiang/QHQReactive下载) 这一章节主要讨论信号的“冷”与“热” 在RAC的世界 ...
- Spring源码分析(六)解析和注册BeanDefinitions
摘要:本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 当把文件转换为Document后,接下来的提取及注册bean就是我们的重 ...
- Spring框架之spring-web web源码完全解析
Spring框架之spring-web web源码完全解析 spring-web是Spring webMVC的基础,由http.remoting.web三部分组成,核心为web模块.http模块封装了 ...
- Retrofit源码设计模式解析(下)
本文将接着<Retrofit源码设计模式解析(上)>,继续分享以下设计模式在Retrofit中的应用: 适配器模式 策略模式 观察者模式 单例模式 原型模式 享元模式 一.适配器模式 在上 ...
随机推荐
- [转载]python:open/文件操作
open/文件操作f=open('/tmp/hello','w') #open(路径+文件名,读写模式) #读写模式:r只读,r+读写,w新建(会覆盖原有文件),a追加,b二进制文件.常用模式 如:' ...
- UVA - 11987 Almost Union-Find[并查集 删除]
UVA - 11987 Almost Union-Find I hope you know the beautiful Union-Find structure. In this problem, y ...
- [2016湖南长沙培训Day4][前鬼后鬼的守护 chen] (动态开点线段树+中位数 or 动规 or 贪心+堆优化)
题目大意 给定一个长度为n的正整数序列,令修改一个数的代价为修改前后两个数的绝对值之差,求用最小代价将序列转换为不减序列. 其中,n满足小于500000,序列中的正整数小于10^9 题解(引自mzx神 ...
- python有超时的windows系统时间设置代码
手边的笔记本用久了,cmos电池可能又没电了.每次开机时间都不对,导致访问一些有https的网页会出现警告信息. 于是找了找通过python脚本设置系统时间的方法,发现了两种,其一是调用socket直 ...
- SharePoint 2013技巧分享系列 - 隐藏Blog和Apps左侧导航菜单
企业内部网中,不需要员工创建Blog或者创建,安装SharePoint应用,因此需要在员工个人Web页面需要隐藏Blog或者Apps导航菜单, 其步骤设置如下: 该技巧适合SharePoint 201 ...
- C++中指针数组的分配与释放
C++中可用new和delete关键字分配和释放内存,但是如果遇到指针数组(或指向指针的指针),分配和释放必须慎重,不然容易造成内存泄漏. 下面用一段代码给出如何使用指向指针的指针来分配和释放内存: ...
- 踩坑所引发出的appendChild方法的介绍
问题描述 最近在做项目时,遇到一个问题,当js生成一个组件后,会注入到页面的某个节点里显示.在组件内部进行了一次注入操作,在调用组件的外部js文件中也进行了一次注入操作,结果发现页面里只生成了一份组件 ...
- Android开发之解决父控件拦截子控件事件问题
以ViewPager为例: public class TopNewsViewPager extends ViewPager { public TopNewsViewPager(Context cont ...
- sublimetext调试
Package Control Sublime Text提供了绝对必要的包管理器.这是安装下面列出的所有插件和主题的最佳方式.继续,在包控制在安装插件. 进入命令面板(ctrl + shift+ p) ...
- tensrflow python [defunct]
在ubuntu上面安装了GPU版本的tensorflow后,很容易碰到zombie thread 的问题,无法正常关闭tensorflow的线程,用ps aux|grep python可以看到 pyt ...