ReactiveCocoa進階(2)

所有的RACSignal都可以進行操作處理,因為所有的操作方法都定義在Stream.h中,因此只要繼承了RACStream就有了操作處理的方法

ReactiveCocoa操作思想:

- Hook(鉤子)思想:改變API(應用程序編程接口,也就是方法)執(zhí)行結(jié)果

一、ReactiveCocoa核心方法:bind

  • ReactiveCocoa的核心方法是bind(綁定),也是RAC的核心開發(fā)方式
  • 之前我們用的開發(fā)方式是賦值,現(xiàn)在我們創(chuàng)建對象的時候,就綁定好以后要做的事情,而不是等待賦值之后在做事情
    • 我們之前展示數(shù)據(jù)到控件上,都是重寫setModel方法,而RAC在一開始創(chuàng)建控件時就綁定好了數(shù)據(jù)。
  • 實際開發(fā)中很少用bind方法,因為bind是RAC底層方法,而RAC已經(jīng)封裝了很多其他方法供我們調(diào)用
// 需求:每次在文本框的輸入后面+sun
[[_textField.rac_textSignal bind:^RACSignalBindBlock _Nonnull{
    return ^RACSignal *(id value, BOOL *stop){
        // 信號一改變,就會執(zhí)行,并且把值傳遞過來
        NSString *result = [NSString stringWithFormat:@"%@%@",value,@"sun"];
        return [RACReturnSignal return:result];
    };
}] subscribeNext:^(id  _Nullable x) {
    NSLog(@"獲取到處理完的數(shù)據(jù) %@",x);
}];

二、ReactiveCocoa操作方法之映射(flattenMap,map)

  • map方法是對于flattenMap方法的封裝,flattenMap是對于bind方法的封裝,攔截源信號的內(nèi)容,改變后傳出
  • map的block的返回值類型為id,flattenMap的block的返回值類型為RACSignal
    • 給訂閱者發(fā)出的值不是信號,一般使用map
    • 給訂閱者發(fā)出的值是信號,一般使用flatternMap
  • map的簡單使用
[[_textField.rac_textSignal map:^id _Nullable(NSString * _Nullable value) {
    NSString *result = [NSString stringWithFormat:@"xmg %@",value];
    return result;
}] subscribeNext:^(id  _Nullable x) {
    NSLog(@"%@",x);
}];
  • flattenMap的簡單使用
[[_textField.rac_textSignal flattenMap:^ RACSignal * (NSString * value) {
    NSString *result = [NSString stringWithFormat:@"sun %@",value];
    return [RACReturnSignal return:result];
}] subscribeNext:^(id  _Nullable x) {
    NSLog(@"%@",x);
}];
  • 當遇到信號中的信號時,要使用flattenMap,map結(jié)合
[[signalOfSignals flattenMap:^RACSignal *(id value) {
    return [value map:^id _Nullable(id  _Nullable value) {
        return [NSString stringWithFormat:@"XMG:%@",value];
    }];
}] subscribeNext:^(id  _Nullable x) {
    NSLog(@"1-%@",x);
}];

三、ReactiveCocoa操作方法之組合

3.1.concat

  • [signalA concat: signalB] 把兩個信號合并為一個信號,當signalA的事件完成,才能觸發(fā)signalB的事件
  • 訂閱后,先接收到signalA的信息,然后接收到signalB的信息
  • 方法內(nèi)部直接訂閱了signalA
  • 應用場景: 需要把兩次請求的數(shù)據(jù)添加到一個數(shù)組,先添加A, 在添加B
concat語法:
    // 創(chuàng)建信號
    RACSubject *signalA = [RACSubject subject];
    RACSubject *signalB = [RACReplaySubject subject];
    NSMutableArray *arrM = [NSMutableArray array];
    // concat
    [[signalA concat: signalB] subscribeNext:^(id  _Nullable x) {
        [arrM addObject:x];
    }];
    // 發(fā)送信號
    [signalB sendNext:@"B"];
    [signalA sendNext:@"A"];
    [signalA sendCompleted];

3.2.then

  • 前面一個信號的事件完成,才能觸發(fā)then后面信號的事件
  • 訂閱后, 只能接收到后一個信號給訂閱者的信息
  • 原理:使用concat連接then返回的信號,忽略之前信號發(fā)出的信息
then語法:
RACSignal *signalA = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
    [subscriber sendNext:@1];
    [subscriber sendCompleted];
    return nil;
}];
[[signalA then:^RACSignal * _Nonnull{
    return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        [subscriber sendNext:@2];
        return nil;
    }];
}] subscribeNext:^(id  _Nullable x) {
    NSLog(@"%@",x);
}];

3.3.merge

  • 把多個信號合并為一個信號, 任何一個信號給訂閱者發(fā)送信息都能監(jiān)聽到
    // 無序的整合信號數(shù)據(jù)
    RACSubject *signalA = [RACSubject subject];
    RACSubject *signalB = [RACSubject subject];
    [[signalA merge:signalB] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    // 發(fā)送
    [signalB sendNext:@"B"];
    [signalA sendNext:@"A"];

3.4.zipWith

  • 把兩個個信號壓縮成一個信號,只有當 兩個信號都給訂閱者發(fā)送數(shù)據(jù)時,才能監(jiān)聽到
  • 返回的x為元組
RACSubject *signalA = [RACSubject subject];
RACSubject *signalB = [RACSubject subject];
[[signalA zipWith:signalB] subscribeNext:^(id  _Nullable x) {
    RACTupleUnpack(NSString *a,NSString *b) = x;
    NSLog(@"%@ %@",a,b);
 }];   
[signalA sendNext:@"A"];
[signalB sendNext:@"B"];

3.5.combineLatest (組合)

  • 把兩個信號組合成一個信號時,和zip一樣
  • 把多個信號合并為一個信號,只有當 所有信號都給訂閱者發(fā)送數(shù)據(jù)時,才能監(jiān)聽到
  • 訂閱后,得到的是各個信號的最新值
  • 返回的x為元組
[[_accountField.rac_textSignal combineLatestWith:_pwdField.rac_textSignal] subscribeNext:^(id  _Nullable x) {
    RACTupleUnpack(NSString *account,NSString *pwd) = x;
    _loginButton.enabled = account.length > 0 && pwd.length;
}];

3.6.reduce(聚合)

  • reduce后的block參數(shù)是自己寫上去的。有幾個信號,就寫幾個參數(shù),每個參數(shù)都是信號給訂閱者發(fā)送的數(shù)據(jù)
  • 底層實現(xiàn):訂閱聚合信號,每次有內(nèi)容發(fā)出,就會執(zhí)行reduce的blcok,把信號內(nèi)容轉(zhuǎn)換成blcok返回的值。
  • 把多個信號給訂閱者發(fā)送的數(shù)據(jù)聚合到一起
// 常見用法:先組合再聚合
[[RACSignal combineLatest:@[_accountField.rac_textSignal,_pwdField.rac_textSignal] 
   reduce:^id (NSString *account, NSString *pwd){
   //這里返回什么,下面Block的x就是什么
   return @(account.length > 0 && pwd.length > 0);
}] subscribeNext:^(id  _Nullable x) {
    _loginButton.enabled = [x boolValue];
}];

四、ReactiveCocoa核心操作方法-filter(過濾)

  • 減少使用if
  • 返回YES才可以給訂閱者發(fā)送數(shù)據(jù)
[[_pwdField.rac_textSignal filter:^BOOL (NSString *value) {
    // 必須要滿足這個條件,才可以給訂閱者發(fā)送數(shù)據(jù)
    return value.length > 6;
}] subscribeNext:^(NSString * _Nullable x) {
    NSLog(@"%@",x);
}];

五、ReactiveCocoa核心操作方法-定時器

interval: onScheduler:

  • RACScheduler:多線程,管理多線程
[[RACSignal interval:1 onScheduler:[RACScheduler mainThreadScheduler]] 
subscribeNext:^(NSDate * _Nullable x) {
    NSLog(@"執(zhí)行了定時器");
}];

六、ReactiveCocoa核心操作方法-delay(延遲執(zhí)行)

// 延遲發(fā)送數(shù)據(jù)
[[[RACSignal createSignal:^RACDisposable *(id <RACSubscriber> subscriber) {
    [subscriber sendNext:@"hello"];
    return nil;
}] delay:2] subscribeNext:^(id  _Nullable x) {
    NSLog(@"%@",x);
}];

遵循NSFastEnumeration協(xié)議的可以當做數(shù)組

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,538評論 3 417
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,761評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,207評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,419評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,959評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,678評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,978評論 2 374