讓你快速上手ReactiveCocoa

很多博客都說RAC好用窘茁,但小編發(fā)現(xiàn)真正缺少的是如何學習RAC的文章哑姚。于是決定自己寫一遍關(guān)于學習ReactiveCocoa的文章,本文主要針對如何從零開始學習ReactiveCocoa譬嚣。

如何學習新的框架

  • 掌握這個框架常用類,常用方法
  • 框架如何設計的,有哪些好的地方

如何導入ReactiveCocoa

Cocoapods是我們的老朋友了方咆。這里我們就使用它票编。

屏幕快照 2017-09-14 上午10.01.24.png
use_frameworks!

platform :ios, “9.0”  

target "RAC練習" do

pod 'ReactiveCocoa', '~> 5.0.0-alpha.5'

end
  • 這里注意use_frameworks!不可以少褪储,不然會報錯。

ReactiveCocoa常用類:

一慧域、RACSignal

  • 能訂閱鲤竹,不能發(fā)送
  • 只能有一個訂閱者
    • 多次訂閱,則訂閱者會多次發(fā)送信息
  • 只能發(fā)送單個值
  • 注意:先訂閱,再發(fā)送
    • RACSubscriber訂閱者辛藻,具備發(fā)送消息能力碘橘。
    • RACDisposable訂閱者被銷毀時候調(diào)用
    // 創(chuàng)建信號
    RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        [subscriber sendNext:@2];
        // 如果不再發(fā)送數(shù)據(jù),最好發(fā)送信號完成吱肌,內(nèi)部會自動調(diào)用[RACDisposable disposable]取消訂閱信號
        [subscriber sendCompleted];
        return [RACDisposable disposableWithBlock:^{
            // 當訂閱者被銷毀的時候就會執(zhí)行
            // 信號發(fā)送完成或者發(fā)送錯誤痘拆,也會執(zhí)行block,取消訂閱信號
            NSLog(@"信號被銷毀");
        }];
    }];
    // 訂閱信號傳的值
    // 底層:創(chuàng)建訂閱者
    // 注意:不能分開訂閱氮墨,要一起訂閱
    [signal subscribeNext:^(id  _Nullable x) {
    } error:^(NSError * _Nullable error) {
    } completed:^{
    }];

二纺蛆、RACSubject

  • 可訂閱,可發(fā)送
  • 可有多個訂閱者
    • 多次訂閱规揪,則訂閱者只發(fā)送信息一次
  • 只能發(fā)送單個值
  • 注意:先訂閱桥氏,再發(fā)送
    // RACSubject語法:
    // 創(chuàng)建信號
    RACSubject *subject = [RACSubject subject];
    // 訂閱
    // 內(nèi)部創(chuàng)建RACSubscriber,并且保存起來
    [subject subscribeNext:^(id  _Nullable x) {
        NSLog(@"第一個訂閱者%@",x);
    }];
    [subject subscribeNext:^(id  _Nullable x) {
        NSLog(@"第二個訂閱者%@",x);
    }];
    // 發(fā)送信號
    // 遍歷所有的訂閱者猛铅,執(zhí)行nextBlock
    [subject sendNext:@1];
  • RACSubject使用場景:一個數(shù)據(jù)需要多個類同時處理-替代代理:
    // 類SUNView中代碼:
    @interface SUNView : UIView
    @property (nonatomic, strong) RACSubject *subject;
    @end
    #import "SUNView.h"
    @implementation SUNView
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:    (UIEvent *)event{
        [_subject sendNext:self];
    }
    @end

    // ViewController中代碼:
    SUNView *v = [[SUNView alloc] init];
    RACSubject *subject = [RACSubject subject];
    // 訂閱
    [subject subscribeNext:^(id  _Nullable x) {
        NSLog(@"點擊了紅色%@",x);
    }];
    v.subject = subject;
    [self.view addSubview:v];

三字支、RACReplaySubject

  • 可訂閱,可發(fā)送
  • 只能有一個訂閱者
  • 可發(fā)送多個值
  • 注意:無所謂先訂閱或先發(fā)送
    // 創(chuàng)建信號
    RACReplaySubject *replaySubject = [RACReplaySubject subject];
    // 發(fā)送信息
    [replaySubject sendNext:@"123"];
    [replaySubject sendNext:@"321"];
    // 訂閱信號
    // 遍歷值奸忽,讓一個訂閱者去發(fā)送多個值
    // 只要訂閱一次祥款,之前所有發(fā)送的值都能獲取到.
    [replaySubject subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];

四、RACSequence:RAC中的集合(數(shù)組)

  • 訂閱集合(獲取數(shù)據(jù))之后月杉,block內(nèi)的操作刃跛,都是在子線程
4.1.OC數(shù)組轉(zhuǎn)化為RACSequence,獲取信號苛萎,訂閱桨昙。( x 為數(shù)組中的單個元素)
NSArray *datas = [NSArray arrayWithContentsOfFile:filePath];
NSMutableArray *arrM = [NSMutableArray array];
// OC數(shù)組轉(zhuǎn)化為RAC數(shù)組,然后獲取信號腌歉,然后訂閱信號(如果數(shù)組中包含的是字典那么蛙酪,返回的x即為字典,免去遍歷數(shù)組的代碼)
[datas.rac_sequence.signal subscribeNext:^(id  _Nullable x) {
    FlagItem *item = [FlagItem itemWithDict:x];
    [arrM addObject:item];
} completed:^{
}];
4.2.OC字典轉(zhuǎn)化為RACSequence翘盖,獲取信號桂塞,訂閱。( x 為單個元組)
NSDictionary *dict = @{@"name" : @"wangsicong", @"money": @100000000};
// 如果是字典那么集合會返回元組RACTuple
[dict.rac_sequence.signal subscribeNext:^(id x) {
    //把元祖解析出來
    RACTupleUnpack(NSString *key, id value) = x;
}];
//把值包裝成元祖
RACTuple *tuple = RACTuplePack(@1, @2, @3);
4.3.OC數(shù)組轉(zhuǎn)化為RACSequence馍驯,調(diào)用map阁危,array函數(shù)。( x 為數(shù)組中的單個元素)
//使用map函數(shù)汰瘫,直接獲取到字典狂打,然后調(diào)用RAC的array方法,直接返回數(shù)組混弥,比上面代碼更加簡潔
arrM = [[datas.rac_sequence map:^id _Nullable(id  _Nullable value) {
    return [FlagItem itemWithDict:value];
}] array];

五趴乡、RACMulticastConnection(多路傳送連接)

  • 為解決 RACSignal被多次訂閱,訂閱者多次發(fā)送信息,而生晾捏!
  • RAC的弱引用:@weakify(self)
  • RAC的強引用:@strongify(self)
    @weakify(self)
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        @strongify(self);
        [self loadData:^(id data) {
            [subscriber sendNext:data];
        }];
        return nil;
    }];
    //RACSignal轉(zhuǎn)化為RACMulticastConnection蒿涎,RACMulticastConnection對象中有signal
    RACMulticastConnection *connection = [signal publish];
    [connection.signal subscribeNext:^(id x) {
    }];
    [connection.signal subscribeNext:^(id x) {
    }];
    [connection connect];

六、RACCommand

6.1.RACCommand語法
  • RACCommand對象內(nèi)部必須返回信號
// 創(chuàng)建Command
RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
    // RACCommand的block
    return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
    [subscriber sendNext:@"你好"];
    [subscriber sendCompleted];
    return nil;
    }];
}];
  • execute 觸發(fā)上面RACCommand的block
// input參數(shù)是@1惦辛;會返回一個信號
[command execute:@1];
6.2.訂閱RACCommand信號
  • execute 獲取RACCommand對象返回的信號
[[command execute:@1] subscribeNext:^(id  _Nullable x) {
     NSLog(@"%@",x);
}];
  • switchToLatest獲取RACCommand對象返回的信號
// switchToLatest: 獲取最近發(fā)送的信號
[command.executionSignals.switchToLatest subscribeNext:^(id  _Nullable x) {
     NSLog(@"%@",x);
}];
  • executionSignals 是信號中的信號劳秋,不是對象返回的信號
[command.executionSignals subscribeNext:^(id  _Nullable x) {
    [x subscribeNext:^(id  _Nullable x) {
    }];
}];
6.3屬性 executing 監(jiān)聽命令是否完成,第一次用skip跳過
[[command.executing skip:1] subscribeNext:^(NSNumber * _Nullable x) {
    BOOL isExecuting = [x boolValue];
    if (isExecuting) {
        NSLog(@"正在執(zhí)行");
    } else {
        NSLog(@"執(zhí)行完成");
    }
}];
6.4.RACCommand使用場景:_loginButton.rac_command
第一種Button使用方式:
_loginButton.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
    return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        [subscriber sendNext:input];
        return nil;
    }];
}];
// 按鈕點擊監(jiān)聽
[_loginButton.rac_command.executionSignals.switchToLatest subscribeNext:^(id  _Nullable x) {
    //x即為input
    NSLog(@"%@",x);
}];
!第二種Button使用方式:
RACSubject *enableSignal = [RACSubject subject];
_loginButton.rac_command = [[RACCommand alloc] initWithEnabled:enableSignal signalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
    return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        [subscriber sendNext:input];
        [subscriber sendCompleted];
        return nil;
    }];
}];
[[_loginButton.rac_command.executing skip:1] subscribeNext:^(NSNumber * _Nullable x) {
    BOOL executing = [x boolValue];
    //這個信息直接被按鈕訂閱
    [enableSignal sendNext:@(!executing)];
}];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末裙品,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子俗或,更是在濱河造成了極大的恐慌市怎,老刑警劉巖,帶你破解...
    沈念sama閱讀 223,126評論 6 520
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辛慰,死亡現(xiàn)場離奇詭異区匠,居然都是意外死亡,警方通過查閱死者的電腦和手機帅腌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,421評論 3 400
  • 文/潘曉璐 我一進店門驰弄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人速客,你說我怎么就攤上這事戚篙。” “怎么了溺职?”我有些...
    開封第一講書人閱讀 169,941評論 0 366
  • 文/不壞的土叔 我叫張陵岔擂,是天一觀的道長。 經(jīng)常有香客問我浪耘,道長乱灵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,294評論 1 300
  • 正文 為了忘掉前任七冲,我火速辦了婚禮痛倚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘澜躺。我一直安慰自己蝉稳,他們只是感情好,可當我...
    茶點故事閱讀 69,295評論 6 398
  • 文/花漫 我一把揭開白布掘鄙。 她就那樣靜靜地躺著颠区,像睡著了一般。 火紅的嫁衣襯著肌膚如雪通铲。 梳的紋絲不亂的頭發(fā)上毕莱,一...
    開封第一講書人閱讀 52,874評論 1 314
  • 那天翅帜,我揣著相機與錄音,去河邊找鬼忘衍。 笑死位他,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的部服。 我是一名探鬼主播唆姐,決...
    沈念sama閱讀 41,285評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼廓八!你這毒婦竟也來了奉芦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,249評論 0 277
  • 序言:老撾萬榮一對情侶失蹤剧蹂,失蹤者是張志新(化名)和其女友劉穎声功,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宠叼,經(jīng)...
    沈念sama閱讀 46,760評論 1 321
  • 正文 獨居荒郊野嶺守林人離奇死亡先巴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,840評論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了冒冬。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片伸蚯。...
    茶點故事閱讀 40,973評論 1 354
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖简烤,靈堂內(nèi)的尸體忽然破棺而出剂邮,到底是詐尸還是另有隱情,我是刑警寧澤横侦,帶...
    沈念sama閱讀 36,631評論 5 351
  • 正文 年R本政府宣布抗斤,位于F島的核電站,受9級特大地震影響丈咐,放射性物質(zhì)發(fā)生泄漏瑞眼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,315評論 3 336
  • 文/蒙蒙 一棵逊、第九天 我趴在偏房一處隱蔽的房頂上張望伤疙。 院中可真熱鬧,春花似錦辆影、人聲如沸徒像。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,797評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锯蛀。三九已至,卻和暖如春次慢,著一層夾襖步出監(jiān)牢的瞬間旁涤,已是汗流浹背翔曲。 一陣腳步聲響...
    開封第一講書人閱讀 33,926評論 1 275
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留劈愚,地道東北人瞳遍。 一個月前我還...
    沈念sama閱讀 49,431評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像菌羽,于是被迫代替她去往敵國和親掠械。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,982評論 2 361