ReactiveCocoa 框架學(xué)習(xí)——框架的使用

如何使用ReactiveCocoa

ReactiveCocoa可以在iOS和OS X的應(yīng)用開發(fā)中使用,對于iOS開發(fā)者,可以將RAC源碼下載編譯后,使用編譯好的libReactiveCocoa-iOS.a文件。
開發(fā)者也可以用CocoaPods來設(shè)置目標(biāo)工程對ReactiveCocoa的依賴,只需要編輯Podfile文件,增加如下內(nèi)容即可:

pod 'ReactiveCocoa', '~> 4.0.2-alpha-1'
Paste_Image.png

一般會(huì)導(dǎo)入不成功
** 報(bào)錯(cuò)提示信息**


Paste_Image.png

需要在podfile加上use_frameworks,重新pod install 才能導(dǎo)入成功(這個(gè)是應(yīng)為框架是swift的緣故)

use_frameworks!
Paste_Image.png

ReactiveCocoa的特點(diǎn)

RAC在應(yīng)用中大量使用了block,由于Objective-C語言的內(nèi)存管理是基于引用計(jì)數(shù) 的,為了避免循環(huán)引用問題,在block中如果要引用self,需要使用@weakify(self)@strongify(self)來避免強(qiáng)引用。另外,在使用時(shí)應(yīng)該注意block的嵌套層數(shù),不恰當(dāng)?shù)臑E用多層嵌套block可能給程序的可維護(hù)性帶來災(zāi)難。
RAC的編程方式和傳統(tǒng)的MVC方式差異巨大,所以需要較長的學(xué)習(xí)時(shí)間。

對于一個(gè)常用框架的學(xué)習(xí)先要了解常用類和項(xiàng)目的基本結(jié)構(gòu)

ReactiveCocoa框架的結(jié)構(gòu) 圖(圖來自刀哥分享, 刀哥Github

psb.png

** RAC中最核心的類RACSiganl**
搞定RACSiganl,這個(gè)類就能用ReactiveCocoa開發(fā)了。

RACSiganl:信號類,一般表示將來有數(shù)據(jù)傳遞,只要有數(shù)據(jù)改變,信號內(nèi)部接收到數(shù)據(jù),就會(huì)馬上發(fā)出數(shù)據(jù)。

先通過一個(gè)簡單的示例來進(jìn)行學(xué)習(xí):


Paste_Image.png

將下面的代碼添加到viewDidLoad方法的最后:

// rac_textSignal 是一個(gè)通過分類實(shí)現(xiàn)的信號。subscribeNext 是訂閱信號。
// ReactiveCocoa框架使用category來為很多基本UIKit控件添加signal。這樣你就能給控件添加訂閱了,text field的rac_textSignal就是這么來的。
[self.usernameTextField.rac_textSignal subscribeNext:^(id x){
  NSLog(@"%@", x);
}];

編譯運(yùn)行,在用戶名輸入框中輸幾個(gè)字。注意console的輸出應(yīng)該和下面的類似。


Snip20151001_3.png
2015-10-01 21:37:04.619 ReactiveCocoaDemo[4212:72362] 1
2015-10-01 21:37:05.967 ReactiveCocoaDemo[4212:72362] 12
2015-10-01 21:37:06.636 ReactiveCocoaDemo[4212:72362] 123
2015-10-01 21:37:07.543 ReactiveCocoaDemo[4212:72362] 1234
2015-10-01 21:37:08.620 ReactiveCocoaDemo[4212:72362] 12345
2015-10-01 21:37:09.079 ReactiveCocoaDemo[4212:72362] 123456
2015-10-01 21:37:09.488 ReactiveCocoaDemo[4212:72362] 1234567
2015-10-01 21:37:10.120 ReactiveCocoaDemo[4212:72362] 12345678

ReactiveCocoa signal(RACSignal)發(fā)送事件流給它的subscriber。目前總共有三種類型的事件:next、error、completed。一個(gè)signal在因error終止或者完成前,可以發(fā)送任意數(shù)量的next事件。在本教程的第一部分,我們將會(huì)關(guān)注next事件。

RACSignal有很多方法可以來訂閱不同的事件類型。每個(gè)方法都需要至少一個(gè)block,當(dāng)事件發(fā)生時(shí)就會(huì)執(zhí)行block中的邏輯。在上面的例子中可以看到每次next事件發(fā)生時(shí),subscribeNext:方法提供的block都會(huì)執(zhí)行。

ReactiveCocoa有很多操作來控制事件流。假設(shè)你只關(guān)心超過3個(gè)字符長度的用戶名,那么你可以使用filter操作來實(shí)現(xiàn)這個(gè)目的。把之前加在viewDidLoad中的代碼更新成下面的:

// filter :過濾器 將信號進(jìn)行過濾,從而得到我們想要的信號。   subscribeNext :訂閱信號。 
**只有訂閱了的信號,信號流才會(huì)起作用。**
[[self.usernameTextField.rac_textSignal
    filter:^BOOL(id value){
         NSString*text = value;
         return text.length > 3;
    }]
        subscribeNext:^(id x){
        NSLog(@"%@", x);
  }];
Paste_Image.png
// 這個(gè)代碼是不會(huì)起作用的。
[self.usernameTextField.rac_textSignal
     filter:^BOOL(id value){
         NSString*text = value;
         return text.length > 3;
     }];

響應(yīng)式編程的本質(zhì)是響應(yīng)鏈條(也就是信號管道),根據(jù)響應(yīng)鏈條來表達(dá)應(yīng)用的功能。


Paste_Image.png

從上面的圖中可以看到,rac_textSignal是起始事件。然后數(shù)據(jù)通過一個(gè)filter,如果這個(gè)事件包含一個(gè)長度超過3的字符串,那么該事件就可以通過。管道的最后一步就是subscribeNext:,block在這里打印出事件的值。

filter操作的輸出也是RACSignal,這點(diǎn)先放到一邊。你可以像下面那樣調(diào)整一下代碼來展示每一步的操作。

// 這個(gè)是將上面的信號管道進(jìn)行拆分
// 1. 先獲取  self.usernameTextField.rac_textSignal 信號
RACSignal *usernameSourceSignal =
    self.usernameTextField.rac_textSignal;
 
// 2. 在過濾信號
RACSignal *filteredUsername =[usernameSourceSignal
  filter:^BOOL(id value){
    NSString*text = value;
    return text.length > 3;
  }];
 
// 3. 訂閱信號
[filteredUsername subscribeNext:^(id x){
  NSLog(@"%@", x);
}];

RACSignal的每個(gè)操作都會(huì)返回一個(gè)RACsignal,這在術(shù)語上叫做連貫接口(fluent interface)。這個(gè)功能可以讓你直接構(gòu)建管道,而不用每一步都使用本地變量。

[[[self.usernameTextField.rac_textSignal
    // 轉(zhuǎn)換信號 將textSignal 轉(zhuǎn)換為NSMumber
    map:^id(NSString*text){
      return @(text.length);
  }]
    // 過濾信號
    filter:^BOOL(NSNumber*length){
      return[length integerValue] > 3;
  }]
     // 訂閱信號
     subscribeNext:^(id x){
      NSLog(@"%@", x);
  }];
Paste_Image.png

新加的map操作通過block改變了事件的數(shù)據(jù)。map從上一個(gè)next事件接收數(shù)據(jù),通過執(zhí)行block把返回值傳給下一個(gè)next事件。在上面的代碼中,map以NSString為輸入,取字符串的長度,返回一個(gè)NSNumber。

Paste_Image.png

能看到map操作之后的步驟收到的都是NSNumber實(shí)例。你可以使用map操作來把接收的數(shù)據(jù)轉(zhuǎn)換成想要的類型,只要它是個(gè)對象。

創(chuàng)建一些信號,來表示用戶名和密碼輸入框中的輸入內(nèi)容是否有效

    // 信號是否有效并返回信號
    RACSignal *validUsernameSignal =
    [self.usernameTextField.rac_textSignal
     map:^id(NSString *text) {
         return @([self isValidUsername:text]);
     }];
    RACSignal *validPasswordSignal =
    [self.passwordTextField.rac_textSignal
     map:^id(NSString *text) {
         return @([self isValidPassword:text]);
     }];
    

    // 將信號進(jìn)行轉(zhuǎn)換 并訂閱信號
    [[validUsernameSignal  map:^id(NSNumber *usernameValid){
          return[usernameValid boolValue] ? [UIColor clearColor]:[UIColor yellowColor];
      }]  subscribeNext:^(UIColor *color){
          self.usernameTextField.backgroundColor = color;
     }];
    
    [[validPasswordSignal  map:^id(NSNumber *passwordValid){
          return[passwordValid boolValue] ? [UIColor clearColor]:[UIColor yellowColor];
      }]  subscribeNext:^(UIColor *color){
          self.passwordTextField.backgroundColor = color;
     }];

上例代碼的簡化

RAC(self.passwordTextField, backgroundColor) = [validPasswordSignal  map:^id(NSNumber *passwordValid){
      return[passwordValid boolValue] ? [UIColor clearColor]:[UIColor yellowColor];
    }];
 
RAC(self.usernameTextField, backgroundColor) = [validUsernameSignal  map:^id(NSNumber *passwordValid){
     return[passwordValid boolValue] ? [UIColor clearColor]:[UIColor yellowColor];
   }];

RAC宏允許直接把信號的輸出應(yīng)用到對象的屬性上。RAC宏有兩個(gè)參數(shù),第一個(gè)是需要設(shè)置屬性值的對象,第二個(gè)是屬性名。每次信號產(chǎn)生一個(gè)next事件,傳遞過來的值都會(huì)應(yīng)用到該屬性上。

Paste_Image.png
  • 注意:
  • 信號類(RACSiganl),只是表示當(dāng)數(shù)據(jù)改變 時(shí),信號內(nèi)部會(huì)發(fā)出數(shù)據(jù),它本身不具備發(fā)送信號的能力,而是交給內(nèi)部一個(gè)訂閱者去發(fā)出。
  • 默認(rèn)一個(gè)信號都是冷信號,也就是值改變了,也不會(huì)觸發(fā),只有訂閱了這個(gè)信號,這個(gè)信號才會(huì)變?yōu)闊嵝盘?,值改變了才?huì)觸發(fā)。
  • 如何訂閱信號:調(diào)用信號RACSignal的subscribeNext就能訂閱。

學(xué)習(xí)博客原文推薦:
ReactiveCocoa - iOS開發(fā)的新框架 ——唐巧的技術(shù)博客
最快讓你上手ReactiveCocoa之基礎(chǔ)篇——袁錚
ReactiveCocoa入門教程——第一部分——BenBeng

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • RAC使用測試Demo下載:github.com/FuWees/WPRACTestDemo 1.ReactiveC...
    FuWees閱讀 6,633評論 3 10
  • 1.ReactiveCocoa常見操作方法介紹。 1.1 ReactiveCocoa操作須知 所有的信號(RACS...
    萌芽的冬天閱讀 1,136評論 0 5
  • 作為一個(gè)iOS開發(fā)者,你寫的每一行代碼幾乎都是在相應(yīng)某個(gè)事件,例如按鈕的點(diǎn)擊,收到網(wǎng)絡(luò)消息,屬性的變化(通過KVO...
    jiajia1118閱讀 844評論 0 2
  • 前言由于時(shí)間的問題,暫且只更新這么多了,后續(xù)還會(huì)持續(xù)更新本文《最快讓你上手ReactiveCocoa之進(jìn)階篇》,目...
    Karos_凱閱讀 1,856評論 0 6
  • 總所周知,臍橙營養(yǎng)豐富,含有人體所必需的各類營養(yǎng)成份。臍橙含有大量維生素C和胡蘿卜素,有助于抑制致癌物的形成,還能...
    90后的橙姑娘閱讀 868評論 0 1

友情鏈接更多精彩內(nèi)容