本文出处:http://www.cnblogs.com/forkasi/p/4886740.html

在项目里,经常会使用这种方式创建一个signal 然后next

    RACSignal *four = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

        NSLog(@"oneSignal createSignal");
[subscriber sendNext:@""];
[subscriber sendCompleted]; return [RACDisposable disposableWithBlock:^{
NSLog(@"oneSignal dispose");
}];
}]; [four subscribeNext:^(id x) {
NSLog(@"fristSignal 1");
}];

有时候我们会想顺序操作分割业务,在原来的signal对象上再next一次

 [four subscribeNext:^(id x) {
NSLog(@"fristSignal 2");
}];

看上去是没有问题的,但是一跑起来就会发现

2015-10-17 00:06:20.050 conatAndThen[4518:2969779] oneSignal createSignal
2015-10-17 00:06:20.051 conatAndThen[4518:2969779] fristSignal 1
2015-10-17 00:06:20.052 conatAndThen[4518:2969779] oneSignal dispose
2015-10-17 00:06:20.053 conatAndThen[4518:2969779] oneSignal createSignal
2015-10-17 00:06:20.053 conatAndThen[4518:2969779] fristSignal 2
2015-10-17 00:06:20.053 conatAndThen[4518:2969779] oneSignal dispose

createSignal 被调用两次,来看看这是为什么

1.createSignal传入createBlock 返回 一个RACDynamicSignal 对象

这个对象保存了didSubscrib的block

2.在subscribNext中传入nextBlock创建一个RACSubscriber对象

3.执行subscribe这个方法

在subscribe中 调用了didSubscribe

并将保存了nextBlock的RACSubscriber对象

4.如果在createBlock中调用了subsribe sendNext的话 subscribe就会调用传入的nextBlock

总的来说

我们在createBlock经常看到的id<RACSubscriber> subscriber

这个subsriber就是在subsrbeNext时创建的,每次执行subscribeNext都会调用createBlock

,这就不难理解为什么createBlock为什么会重复执行

这根本就是不同的RACSubscriber

RAC 通过RACSignal 的multicast 方法来解决这个问题

这个方法返回一个RACMulticastConnection对象 调用connect 方法后,再获取signal属性,createBlock被调用多次的问题就会得到解决

    RACMulticastConnection *connection = [four multicast:[RACReplaySubject subject]];

    [connection connect];

    [connection.signal subscribeNext:^(id x) {
NSLog(@"fristSignal 1");
}]; [connection.signal subscribeNext:^(id x) {
NSLog(@"fristSignal 2");
}];

结果

2015-10-17 00:16:55.053 conatAndThen[4576:2977593] oneSignal createSignal
2015-10-17 00:16:55.054 conatAndThen[4576:2977593] oneSignal dispose
2015-10-17 00:16:55.055 conatAndThen[4576:2977593] fristSignal 1
2015-10-17 00:16:55.056 conatAndThen[4576:2977593] fristSignal 2

来看看RACMulticastConnection是怎么解决问题的

mulitcast 这个方法,首先就创建了一个RACMulticastConnection对象保存参数起来

connect 方法里面会对sourceSignal subscribe 也就是执行createBlock

所以我们看到是fristSignal 1比dispose先一步执行

这时我们在后续操作的subscriNext的signal已经不是原来的signal了,

而是didsubscribeBlock为空的signal,所以不管后面有多少次subscribNext都不会让createBlock重复执行

ReactiveCocoa 谈谈RACMulticastConnection的更多相关文章

  1. ReactiveCocoa 谈谈concat

    今天的一个业务流程,业务流程大概就是这样的 1.从CoreData中获取之前的数据 2.更新界面 3.从网络获取数据 4.判断获取结果 5.处理错误判断 6.更新界面 7.判断结果numberOfNe ...

  2. RAC & MVVM 学习资料整理

    最后更新:2017-01-23 参考链接: MVVM奇葩说 MVVM 介绍 Model-View-ViewModel for iOS [译] 唐巧--被误解的 MVC 和被神化的 MVVM React ...

  3. 最快让你上手ReactiveCocoa之基础篇

    前言 很多blog都说ReactiveCocoa好用,然后各种秀自己如何灵活运用ReactiveCocoa,但是感觉真正缺少的是一篇如何学习ReactiveCocoa的文章,这里介绍一下. 1.Rea ...

  4. ReactiveCocoa学习

    ReactiveCocoa常见类 6.1RACSiganl:信号类,一般表示将来有数据传递,只要有数据改变,信号内部接收到数据,就会马上发出数据. 注意: 信号类(RACSiganl),只是表示当数据 ...

  5. IOS ReactiveCocoa

    一 前提: 在iOS开发过程中,当某些事件响应时,需处理的某些业务逻辑 Eg. 按钮点击:action ScrollView滚动:delegate 属性值改变:KVO ReactiveCocoa为事件 ...

  6. 【iOS】小项目框架设计(ReactiveCocoa+MVVM+AFNetworking+FMDB)

    上一个项目使用到了ReactiveCocoa+MVVM+AFNetworking+FMDB框架设计,从最初的尝试,到后来不断思考和学习,现在对这样一个整体设计还是有了一定了理解与心得.在此与大家分享下 ...

  7. ReactiveCocoa学习总结

    最近一直断断续续学习关于ReactiveCocoa的知识内容,对于它的一些基础内容将通过本文进行一个总结,主要是一些入门知识 一:RACSignal一些运用 @interface RACSignalT ...

  8. ReactiveCocoa基础知识内容

    本文记录一些关于学习ReactiveCocoa基础知识内容,对于ReactiveCocoa相关的概念如果不了解可以网上搜索:RACSignal有很多方法可以来订阅不同的事件类型,ReactiveCoc ...

  9. ReactiveCocoa比较区分replay, replayLast和replayLazily

    一直搞不清楚replayLazily和replay的区别可以直接跳到最后看. 原文:http://spin.atomicobject.com/2014/06/29/replay-replaylast- ...

随机推荐

  1. Html笔记(九)头标签

    头标签: <head> 头标签都放在 <head> </head> 头部分之间.包括:title base meta link <title> :指定浏 ...

  2. shell常用命令总结

    统计文件行数 wc -l filename grep -c "" filename sed -n '$=' filename awk 'END{print NR}' filenam ...

  3. 整合maven,jetty,jrebel进行debug调试

    整合maven,jetty,jrebel进行调试 maven配置 这个网上有很多,验证mvn是否配置正确: Jrebel配置 解压至目录,不建议目录名有空格 ,破解包下载 参考: http://zer ...

  4. openstack 虚拟机流量

  5. 函数(C++ Primer读书笔记)

    C++ Primer 第五版课后题 练习6.32 :下面的函数合法吗?如果合法,说明其功能:如果不合法,修改其中的错误并解释原因. #include <iostream> using na ...

  6. clock_t与time_t的区别及联系

    clock_t <ctime> Clock type Type capable of representing clock tick counts and support arithmet ...

  7. tomcat热部署,更改java类不用重新加载context

    修改类后,tomcat热部署会重新加载整个项目的context,影响开发效率.网上查的大多数是将server的modules标签中Auto Reload项改为Disabled,但是没有效果. 使用以下 ...

  8. C# 读取 timestamp 时间戳 值为byte[] 类型时转换为时间戳字符串

    C# 中如何读取出来的时间戳为 byte[] 类型的话,用以下方式转换成 16进制字符串 string tmpUfts = "0x"+ BitConverter.ToString( ...

  9. 使用bash判断PATH中是否存在某个路径

    在source设置环境变量的时候,有些时候可能会设置两次,导致增加系统的路径搜索时间,或者让自己看环境变量的时候搞得怪不爽的. 为了解决这个问题,我们可以在设置相应的环境变量之前,先判断一下是否已经设 ...

  10. Android开发:TextView真正可控、不需要焦点的水平滚动--这才是真正的跑马灯

    网上的TextView做跑马灯,大多都是要用到焦点,而且字数要超出滚动区域宽度才能实现滚动,使用起来十分不方便. 这里实现一种真正可控的滚动 (1)不需要焦点 (2)任意字数 (3)滚动从滚动区域右边 ...