iOS:RAC进阶之冷热信号

前言

之前我分析了一下源码并且用自己理解的伪代码来实现了这种信号简单的传递流程,并且在说到subject父子的时候我们留下了一个小疑问,的回掉触发时机是在订阅的时候,这样的操作会导致创建时候的didscriberblock被调用好几次,所以引发了人们对于signal优化的思考。

冷信号&热信号

冷信号和热信号的概念我第一次为了加深自己的印象在一片文章中,文章中只是解释了表面意思,个人认为没有考虑到本质。后来发现了美团大众点评技术团队的文章,第一次看的时候是在没有看任何源码的情况下看的,当时真的是一脸懵逼,后来看了下基本的源码重新看了下他们的文章,就觉得通俗易懂了。
(更新一下,我的racsignal的文章中说到了是rac作者创建出的冷热信号概念是不对的,他只是在文章中说出了signal对部分副作用的影响,作者只提到了副作用的概念,冷热信号概念来自.NET的RX)

  • 差异化的概念
    1.冷信号是指当我们订阅者订阅了这个信号,我们的信号才开始发送消息。并且冷信号只针对于一个订阅者不支持多个订阅者同接收。
    2.热信号是指无论你有没有订阅者,只要你发送了信号并且我这个信号存在,我就会进行推送。并且热信号支持多个订阅者同时接收。

  • 对号入座
    看完上边冷热信号概念,我们对号入座一波首先我们能确定的就是:
    1.RacSignal就是冷信号,可以做个实验

 RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        
       [[RACScheduler mainThreadScheduler] afterDelay:2 schedule:^{
            [subscriber sendNext:@"1"];
            
            [subscriber sendNext:@"2"];
        }];

        return nil;
    }];
    
    [signal subscribeNext:^(id x) {
        NSLog(@"subscriber1: %@", x);
    }];
    [signal subscribeNext:^(id x) {
        NSLog(@"subscriber2: %@", x);
    }];

控制台打印:
01:02:53.220464+0800 RACOne[52411:2578142] subscriber1: 1
01:02:53.220684+0800 RACOne[52411:2578142] subscriber1: 2
01:02:53.220863+0800 RACOne[52411:2578142] subscriber2: 1
01:02:53.221321+0800 RACOne[52411:2578142] subscriber2: 2

可以看出他的确完全符合冷信号的概念。首先订阅是这个发送的触发时机,只有一个block订阅了他才会发送信号并且产生订阅回掉。这一系列也解释了为什么只有订阅了才会发送信号的原因。其次发送信号都是在订阅时候调用的而订阅者单一单线程操作所以才会执行完第一个订阅者在执行第二个订阅者。

  1. RacSubject父子是热信号。
    注意一下这里为什么racreplaysubject也是热信号,虽然他们也是订阅了才会发送信号,但是他们的关注点是时间这条线,支持多订阅者同时发送,而signal关注的是订阅这条线,单订阅者订阅
    实验如下:
 RACSubject *subject = [RACSubject subject];
    RACReplaySubject *replaySubject = [RACReplaySubject subject];
    
    [subject sendNext:@"1"];
    [replaySubject sendNext:@"1"];
    
    [[RACScheduler mainThreadScheduler] afterDelay:1 schedule:^{
        [subject sendNext:@"2"];
        [replaySubject sendNext:@"2"];
    }];
    
    [subject subscribeNext:^(id x) {
         NSLog(@"subscriber1: %@", x);
    }];
    
    [subject subscribeNext:^(id x) {
         NSLog(@"subscriber2: %@", x);
    }];
    
    [replaySubject subscribeNext:^(id x) {
         NSLog(@"Replaysubscriber1: %@", x);
    }];
    
    [replaySubject subscribeNext:^(id x) {
         NSLog(@"Replaysubscriber2: %@", x);
    }];

控制台:
01:27:03.229905+0800 RACOne[52618:2590686] Replaysubscriber1: 1
01:27:03.230147+0800 RACOne[52618:2590686] Replaysubscriber2: 1
01:27:04.230362+0800 RACOne[52618:2590686] subscriber1: 2
01:27:04.230538+0800 RACOne[52618:2590686] subscriber2: 2
01:27:04.230755+0800 RACOne[52618:2590686] Replaysubscriber1: 2
01:27:04.230869+0800 RACOne[52618:2590686] Replaysubscriber2: 2

副作用

// racSiganl创建时对于副作用的阐述
Note:** The `didSubscribe` block is called every time a new subscriber
subscribes. Any side effects within the block will thus execute once for each
subscription, not necessarily on one thread, and possibly even
simultaneously!

rac是一套基于cocoa的FRP框架,FRP又称之为函数式响应编程,既然说到函数,假如是纯函数,外部传入只在函数中有改变而不对外部做出修改,但是针对于OOP中肯定包含副作用的地方。具体副作用是什么,产生在哪:

  • 函数执行过程中,修改了外部的变量,例如在一个函数中修改了类中的属性,常量。例:在OC的block修改了类中的属性就是一个副作用。
  • 函数处理过程中包含触发事件,代理,block,notification等也会有函数副作用的存在
  • 函数处理过程中,受到锁的影响也属于。
  • 函数中针对传入指针地址也属于,内部修改后对外部修改。

那么在编程中,这些场景基本都是编程中常见的,就是你用户点到了哪里触发了事件都属于副作用。可以说在日常编程中,副作用基本都存在,也可以这么说我们的编程就是为了产生副作用。

那么如何才能避免副作用呢?副作用又会在什么场景发挥出他们邪恶的一面呢?冷热信号和副作用有什么关系呢?

技术参考美团点评团队:https://tech.meituan.com/ 归档的2015年几期
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345