iOS-RAC学习笔记(二)——RACSignal订阅
来源:互联网 发布:科学引文索引数据库 编辑:程序博客网 时间:2024/06/07 04:10
RACSignal可以说是RAC中最重要的类。RACSignal的订阅是使用RAC的核心机制。
1. RACSignal 订阅机制
a) RACSignal的创建:RACSignal的创建通常是使用+createSignal:这个方法创建出来的。传入参数是一个(传参是RACSubscriber的一个实例,返回是RACDisposable实例)的block;RACSignal里面有一个didSubscribe的成员变量,创建的时候把传入的block赋值给这个didSubscribe。
b) RACSignal的订阅操作:[RACSignal subscribeNext]这个就是RACSignal的订阅方法。以下分几步来说明。
- 在使用这个方法的时候,会创建出一个RACSubscriber的实例(中间操作,对使用方透明),该实例实现了RACSubscriber(protocol),拥有三个block的属性,分别对应next,error,complete,即使用方调用[RACSignal subscribeNext:error:complete]传入的三个block。
- [RACsignal subscribe:(传参是上面创建的实例)O]之后会实际进入这个方法。这个方法的核心目的,就是执行RACSignal的didSubscribe这个block,参数就是O
- 在didSubscribe这个执行过程中,一般都会有[subscriber sendNext/Error/complete],而这个方法的内部其实就是走subscriber的next,error,complete对应的block,也就是在[RACSignal subscribeNext]传入的各个block
在最后一步中,深入到源码:当error或者是complete对应的block走过一次,subscriber的所有block属性都会被置为nil,不会再接受任何的数据,也就意味着本次订阅已经结束。
2. RACSignal 订阅Demo
RACSignal*signal = [RACSignalcreateSignal:^RACDisposable*(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"first value"];
return nil;
}];
[signal subscribeNext:^(idx) {
NSLog(x);
[subscriber sendNext:@"first value"];
return nil;
}];
[signal subscribeNext:^(idx) {
NSLog(x);
}];
如上代码,首先我们创建了一个简单的RACSignal的实例。源码如下,可以看到createSignal后面的block是直接复制到signal的didSubcribe这个对象属性中。
+ (RACSignal*)createSignal:(RACDisposable* (^)(id<RACSubscriber> subscriber))didSubscribe {
RACDynamicSignal*signal = [[selfalloc]init];
signal->_didSubscribe= [didSubscribe copy];
return[signal setNameWithFormat:@"+createSignal:"];
RACDynamicSignal*signal = [[selfalloc]init];
signal->_didSubscribe= [didSubscribe copy];
return[signal setNameWithFormat:@"+createSignal:"];
}
signal之后直接被订阅,源码如下,可以看到先用subscribeNext后面的block构造出一个RACSubscriber的对象。然后去这个对象实际订阅这个signal。所以,我觉得RACSubscriber这个对象在订阅过程对使用者几乎是透明的。
- (RACDisposable*)subscribeNext:(void(^)(idx))nextBlock {
NSCParameterAssert(nextBlock !=NULL);
RACSubscriber*o = [RACSubscribersubscriberWithNext:nextBlockerror:NULLcompleted:NULL];
return[selfsubscribe:o];
return[selfsubscribe:o];
}
signal被这个订阅,主要是为了让signal的didSubcribe这个block运行。如下源码中划线的那部分。
- (RACDisposable*)subscribe:(id<RACSubscriber>)subscriber {
NSCParameterAssert(subscriber !=nil);
RACCompoundDisposable*disposable = [RACCompoundDisposablecompoundDisposable];
subscriber = [[RACPassthroughSubscriberalloc]initWithSubscriber:subscribersignal:selfdisposable:disposable];
if(self.didSubscribe!= NULL) {
RACDisposable*schedulingDisposable = [RACScheduler.subscriptionSchedulerschedule:^{
RACDisposable*innerDisposable =self.didSubscribe(subscriber);
[disposable addDisposable:innerDisposable];
}];
[disposable addDisposable:schedulingDisposable];
}
returndisposable;
NSCParameterAssert(subscriber !=nil);
RACCompoundDisposable*disposable = [RACCompoundDisposablecompoundDisposable];
subscriber = [[RACPassthroughSubscriberalloc]initWithSubscriber:subscribersignal:selfdisposable:disposable];
if(self.didSubscribe!= NULL) {
RACDisposable*schedulingDisposable = [RACScheduler.subscriptionSchedulerschedule:^{
RACDisposable*innerDisposable =self.didSubscribe(subscriber);
[disposable addDisposable:innerDisposable];
}];
[disposable addDisposable:schedulingDisposable];
}
returndisposable;
}
signal执行didSubcribe中,有了[subscribersendNext:@"first value”];这句代码,实际是执行subscribe的next block,也就是我们前面最简单的NSLog(X)。源码如下。
- (void)sendNext:(id)value {
@synchronized(self) {
void(^nextBlock)(id) = [self.nextcopy];
if(nextBlock == nil) return;
nextBlock(value);
}
@synchronized(self) {
void(^nextBlock)(id) = [self.nextcopy];
if(nextBlock == nil) return;
nextBlock(value);
}
}
虽说例子简单,但是我们可以看到signal中值的流向,以及监听signal的本质。各个block之间,一个扣着一个,代码的初始可读性可能比较难理解,但是真正理解之后,你会发现RAC真的很神奇。
0 0
- iOS-RAC学习笔记(二)——RACSignal订阅
- iOS-RAC学习笔记(三)——RACSignal信号流改头换面的祖师Bind
- iOS-RAC学习笔记(一)——RACStream
- iOS RAC学习笔记一
- iOS-Network学习笔记(二)——NSURLConnection
- JMS学习笔记(五)——持久的订阅
- iOS学习笔记(二)——Hello iOS
- iOS学习笔记(二)——Hello iOS
- iOS学习笔记(二)——Hello iOS
- 初识RAC-002--RACSignal类
- IOS学习笔记——UITableView (二)
- IOS学习笔记36——UIPasteboard/UIMenuController(二)
- iOS学习笔记——表视图二(编辑)
- IOS学习笔记——object-C基础 (二)
- IOS学习笔记——基础界面 (二)
- IOS学习笔记31—两个ViewController间传值(二)
- IOS学习笔记31—两个ViewController间传值(二)
- IOS学习笔记31—两个ViewController间传值(二)
- 删除链表中的重复元素
- java基于spring框架上传文件
- 写时拷贝
- 都在做百度SEO,你是否真的了解百度?
- [转]【坐在马桶上看算法】算法2:邻居好说话:冒泡排序--作者:ahalei
- iOS-RAC学习笔记(二)——RACSignal订阅
- Spring框架介绍
- 反射の从Class建立对象
- 终于推开那扇门
- TPL——取消一个Task
- 微信公众平台jsapi开发教程(1)获取jsapi_ticket
- 美化 checkbox
- iOS图片拉伸技巧
- 苹果微信版语音播放支持mp3安卓微信语音播放支持的是ogg