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中的应用: 适配器模式 策略模式 观察者模式 单例模式 原型模式 享元模式 一.适配器模式 在上 ...
随机推荐
- postman使用之二:数据同步和创建测试集
数据同步 启动postman 后在右上角可以登录账号,登录后就可以同步自己的api测试脚本,连上网在办公区在家都可以同步. 创建测试集 1.点击collections,点击add folder 2.c ...
- Serial Port Programming using Win32 API(转载)
In this tutorial we will learn How to communicate with an external device like a microcontroller boa ...
- Android UI组件----AppWidget控件入门详解
Widget引入 我们可以把Widget理解成放置在桌面上的小组件(挂件),有了Widget,我们可以很方便地直接在桌面上进行各种操作,例如播放音乐. 当我们长按桌面时,可以看到Widget选项,如下 ...
- Winform(DataGridView)控件及通过此控件中实现增删改查
DataGridView:显示数据表,通过此控件中可以实现连接数据库,实现数据的增删改查 一.后台数据绑定: List<xxx> list = new List<xxx> ...
- 脏检查and刷新机构
---恢复内容开始--- 脏检查:当食物提交时,Hiberante会对Session中持久状态的对象进行加测,判断对象的数据是否发生了变化 为什么要进行脏检查?, 解析:如果对象发生了改变,就需要将改 ...
- [No00006F]总结C#获取当前路径的各种方法
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- Intellij Idea中定制getter setter的模板
Alt + Ins, 调出快捷菜单后选择 Getter and Setter, 在对话框里, 选择对应的template, 右侧点开后, 可以新建自己的模板并编辑 将getter和setter都生成到 ...
- thrift 一个有意思的特性:Class名称无关性
最近开发的一个项目,后端采用thrift框架来提供rpc服务(java语言实现),然后前端采用php语言来生成thrift client调用后台RPC服务.由于某些原因,上周我把thrift定义文件中 ...
- [[iso教程]] 《4个月ios实体教程》全网最新、最全ios视频教程
全网最新.最全ios视频教程 内容简介 <ios实体教程>主要介绍如何使用iOS提供的强大工具集创建iOS应用.全视频对iOS操作系统做了全面的介绍,首先讲解如何构建应用程序的用户界面,涵 ...
- Asp.Net MVC<四>:路由器
路由的核心类型基本定义于System.Web.dll中,路由机制同样可应用与Web Forms,实现请求地址和物理文件的分离. web form中使用路由器的示例 路由配置 protected voi ...