iOS开发RAC学习笔记(七)信号的副作用以及冷信号和热信号区别的个人见解

github源代码地址

冷信号和热信号

  • 这里感谢cocoachina论坛Noah前辈对我的耐心讲解,同时本文参考了臧成威前辈的文章

冷热信号的理解

以前我对冷信号和热信号的认知就是没订阅的就是冷信号,订阅了的就是热信号,但是最近研究副作用时看了几篇文章打破了我以前的观点.例如RACSignal一般创建出来就是冷信号,RACSubject,RACComand内部返回的信号, RACMulticastConnect这些就是热信号,区别就好比冷信号是一段视频,发过来可以完整的接收到,而热信号就好比是直播,你在订阅的时候有可能信息错过了的话就会收不到.

实际上冷热信号的区分并不是这样的,热信号指,即使外部没有订阅,里面已经源源不断发送值了,你在订阅的时候如果前面的信号错过了就错过了不会再有,这就是为何RACSubject为何要先订阅才能收到信号的原因;冷信号因为每次订阅都会执行一次,每个订阅都是独立行为。这和我们是否去订阅他并没有什么直接的关系,在RAC2中 RACSignal是信号,RACSubject是热信号,RACSignal和子类排除RACSubject是冷信号,而在RAC4中signal是热信号 SignalProducer是冷信号.

我们一般使用热信号的时候会非常谨慎的使用,因为RACSubject会被滥用太方便了,我们一般会使用replay*的方法或者multicast、publish方法来转化或者创建热信号.

RACSubject即使有多少个订阅者,它都只会执行一次,并将结果返回。另外RACMulticastConnection这种内部实现实际上是多个订阅者订阅了一个subject,控制执行行为并不是通过被订阅,而是手动控制的

对RAC副作用的个人理解

副作用指的就是RAC改变了外界的状态(例如全局属性的赋值,多次网络请求,线程锁等),这些可能会导致一个问题,那就是同样的输入可能会导致不同的输出,同时也增加了我们排查代码错误的难度.以网络请求为例,现实中一般是不会这么用的,这里只是举个例子.请求若使用冷信号,我们对这个冷信号在进行一些操作的时候,臧成威前辈讲其实内部对一些信号的操作是再次订阅的过程,那么最后你可能会导致多次请求的问题出现,这便可以理解为副作用.严格地讲iOS开发其实就是一个在创造副作用的过程.现实中我们一般会把请求放到viewmodel中,只请求一个数据,然后将数据转成相应的属性暴露在.h文件,然后控制器在和数据进行绑定,这样做非常的优雅.

冷信号转热信号

这是臧成威前辈给出的冷信号转热信号比较常用的方法,他比subject直接订阅冷信号的优点在于例如subject的订阅者提前终止了订阅,而subject并不能终止对coldSignal的订阅,具体实现代码如下:

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

            NSLog(@"Cold signal be subscribed.");

            [[RACScheduler mainThreadScheduler] afterDelay:1.5 schedule:^{

                [subscriber sendNext:@"A"];

            }];

            [[RACScheduler mainThreadScheduler] afterDelay:3 schedule:^{

                [subscriber sendNext:@"B"];

            }];

            [[RACScheduler mainThreadScheduler] afterDelay:5 schedule:^{

                [subscriber sendCompleted];

            }];

            return nil;

        }];

    RACSubject *subject = [RACSubject subject];

    NSLog(@"Subject created.");

    //RACMulticastConnection:用于当一个信号,被多次订阅时,为了保证创建信号时,避免多次调用创建信号中的block,造成副作用,可以使用这个类处理。
    //也可以通过signal publish创建
    RACMulticastConnection *multicastConnection = [coldSignal multicast:subject];

    RACSignal *hotSignal = multicastConnection.signal;

    [[RACScheduler mainThreadScheduler] afterDelay:2 schedule:^{

        [multicastConnection connect];

    }];

    [hotSignal subscribeNext:^(id x) {

        NSLog(@"Subscribe 1 recieve value:%@.", x);

    }];

    [[RACScheduler mainThreadScheduler] afterDelay:4 schedule:^{

        [hotSignal subscribeNext:^(id x) {

            NSLog(@"Subscribe 2 recieve value:%@.", x);

        }];

    }];
  • 另一种写法

      RACSignal *coldSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    
          NSLog(@"Cold signal be subscribed.");
    
          [[RACScheduler mainThreadScheduler] afterDelay:1.5 schedule:^{
    
              [subscriber sendNext:@"A"];
    
          }];
    
          [[RACScheduler mainThreadScheduler] afterDelay:3 schedule:^{
    
              [subscriber sendNext:@"B"];
    
          }];
    
          [[RACScheduler mainThreadScheduler] afterDelay:5 schedule:^{
    
              [subscriber sendCompleted];
    
          }];
    
          return nil;
    
      }];
    
      RACSubject *subject = [RACSubject subject];
    
      NSLog(@"Subject created.");
    
      RACMulticastConnection *multicastConnection = [coldSignal multicast:subject];
    
      RACSignal *hotSignal = multicastConnection.autoconnect;
    
      [[RACScheduler mainThreadScheduler] afterDelay:2 schedule:^{
    
          [hotSignal subscribeNext:^(id x) {
    
              NSLog(@"Subscribe 1 recieve value:%@.", x);
    
          }];
    
      }];
    
      [[RACScheduler mainThreadScheduler] afterDelay:4 schedule:^{
    
          [hotSignal subscribeNext:^(id x) {
    
              NSLog(@"Subscribe 2 recieve value:%@.", x);
    
          }];
    
      }];
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容