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

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

  1. RACSignal *four = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
  2.  
  3. NSLog(@"oneSignal createSignal");
  4. [subscriber sendNext:@""];
  5. [subscriber sendCompleted];
  6.  
  7. return [RACDisposable disposableWithBlock:^{
  8. NSLog(@"oneSignal dispose");
  9. }];
  10. }];
  11.  
  12. [four subscribeNext:^(id x) {
  13. NSLog(@"fristSignal 1");
  14. }];

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

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

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

  1. 2015-10-17 00:06:20.050 conatAndThen[4518:2969779] oneSignal createSignal
  2. 2015-10-17 00:06:20.051 conatAndThen[4518:2969779] fristSignal 1
  3. 2015-10-17 00:06:20.052 conatAndThen[4518:2969779] oneSignal dispose
  4. 2015-10-17 00:06:20.053 conatAndThen[4518:2969779] oneSignal createSignal
  5. 2015-10-17 00:06:20.053 conatAndThen[4518:2969779] fristSignal 2
  6. 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被调用多次的问题就会得到解决

  1. RACMulticastConnection *connection = [four multicast:[RACReplaySubject subject]];
  2.  
  3. [connection connect];
  4.  
  5. [connection.signal subscribeNext:^(id x) {
  6. NSLog(@"fristSignal 1");
  7. }];
  8.  
  9. [connection.signal subscribeNext:^(id x) {
  10. NSLog(@"fristSignal 2");
  11. }];

结果

  1. 2015-10-17 00:16:55.053 conatAndThen[4576:2977593] oneSignal createSignal
  2. 2015-10-17 00:16:55.054 conatAndThen[4576:2977593] oneSignal dispose
  3. 2015-10-17 00:16:55.055 conatAndThen[4576:2977593] fristSignal 1
  4. 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. 曲面Shader

    这是一个能让平面呈现出曲面效果的Shaer. 代码: Shader "Custom/CurvedWorld"{ Properties { // Diffuse texture _M ...

  2. [九度OJ]1431.Sort(寻找前m大数并排序)

    原题链接:http://ac.jobdu.com/problem.php?pid=1431 题目描述: 给你n个整数,请按从大到小的顺序输出其中前m大的数. 输入: 每组测试数据有两行,第一行有两个数 ...

  3. bzoj 1878 [SDOI2009]HH的项链(离线处理+BIT)

    Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH不断地收集新的贝壳,因此, 他的项链变 ...

  4. Codeforces2B - The least round way(DP)

    题目大意 给定一个N*N的格子,每个格子里有一个非负数,要求你找出从左上角到右下角的一条路径,使得它满足路径上的格子里的数全部乘起来的积尾部0最少 题解 如果要产生0肯定是2*5得出来的,最终的乘积可 ...

  5. A Tour of Go Struct Literals

    A struct literal denotes a newly allocated struct value by listing the values of its fields. You can ...

  6. Grails教程之--我的理解

    最近工作中接触到了Grails,对于这门技术,网上的资料不算太多,有的基本也是大同小异.我打算边学边写一些东西,毕竟是一个学习的过程,写的东西如果有错误或者理解不正确的地方,还希望大家能指出来.帮助我 ...

  7. 对css中的定位属性postion刨根解牛

    定位的基本思想很简单: 它允许你定义元素框相对于其正常位置应该出现的位置(relative),或者相对于父元素(absolute).另一个元素甚至浏览器窗口本身的位置(fixed).显然,这个功能非常 ...

  8. JBPM学习(三):管理流程定义

    概念: ProcessDefinition,流程定义:一个流程的步骤说明,如一个请假流程.报销流程.是一个规则. ProcessDefinition,流程定义对象,是解析.jpdl.xml文件得到流程 ...

  9. Java实现文件的RSA和DES加密算法

    根据密钥类型不同将现代密码技术分为两类:对称加密算法(秘密钥匙加密)和非对称加密算法(公开密钥加密) 对称钥匙加密系统是加密和解密均采用同一把秘密钥匙,而且通信双方都必须获得这把钥匙,并保持钥匙的秘密 ...

  10. RHCA学习笔记:RH442-Unit9内核定时与进程延时

      Unit 9 Kernel Timing and Process Latency 内核定时与进程延时 学习目标: A.了解CPU 是怎样追踪时间的 B.调整CPU的访问次数 C.调整调度延时 D. ...