初認(rèn)RAC

ReactiveCocoa的核心:

信號,沒錯就是信號,發(fā)了信號要干嘛干嘛,講白了就是一個事件流;

那么我們來把這件事做一個形象的比喻:

可以把信號想象成水龍頭,只不過里面不是水,
而是玻璃球(value),直徑跟水管的內(nèi)徑一樣,
這樣就能保證玻璃球是依次排列,不會出現(xiàn)并排的情況
(數(shù)據(jù)都是線性處理的,不會出現(xiàn)并發(fā)情況)。
水龍頭的開關(guān)默認(rèn)是關(guān)的,除非有了接收方(subscriber),才會打開。
這樣只要有新的玻璃球進(jìn)來,就會自動傳送給接收方。
可以在水龍頭上加一個過濾嘴(filter),不符合的不讓通過,
也可以加一個改動裝置,把球改變成符合自己的需求(map)。
也可以把多個水龍頭合并成一個新的水龍頭(combineLatest:reduce:),
這樣只要其中的一個水龍頭有玻璃球出來,
這個新合并的水龍頭就會得到這個球。

需要說明的是因為RAC使用大量的block,請避免循環(huán)引用

例如:

[RACObserve(self,username) subscribeNext:^(NSString *newName){
    NSLog(@"Name changed to %@",newName);
}];
RACObserve使用kvo來監(jiān)聽username的變化,只要有變化就會執(zhí)行block。
但不是所有的property都可以被RACObserve,該property必須支持KVO,比如NSURLCache的currentDiskUsage就不能被RACObserve。

Signal和Subscriber

Signal獲取到數(shù)據(jù)后,會調(diào)用Subscriber的sendNext,
 sendComplete, sendError方法來傳送數(shù)據(jù)給Subscriber,Subscriber自然也有方法來獲取傳過來的數(shù)據(jù),如:
[signal subscribeNext:error:completed]。這樣只要沒有sendComplete和sendError,
新的值就會通過sendNext源源不斷地傳送過來.
ReactiveCocoa signal(RACSignal)
發(fā)送事件流給它的subscriber。

目前共有三種類型的事件:

 next、__error__、completed。

一個signal在因error終止或者完成前,可以發(fā)送任意數(shù)量的next事件.
RACSignal有很多方法可以來訂閱不同的事件類型。
每個方法都需要至少一個block,當(dāng)事件發(fā)生時就會執(zhí)行block中的邏輯。
ReactiveCocoa 框架使用 category 來為很多基本UIKit控件添加signal。
這樣就能給控件添加訂閱了,比如 text field 的 rac_textSignalRACSignal的每個操作都會返回一個RACsignal,
這在術(shù)語上叫做連貫接口(fluent interface)。這個功
能可以讓你直接構(gòu)建管道,而不用每一步都使用本地變量。


片段解析:

  • 只要 text 有變化, 將 text 發(fā)送給 Subscriber

    [self.usernameTextField.rac_textSignal subscribeNext:^(id x){
     NSLog(@"%@", x);
    

    }];

篩選長度 >3, 滿足則發(fā)送給 Subscriber
  [[self.usernameTextField.rac_textSignal
  filter:^BOOL(NSString *text){
    return text.length > 3;
  }]
     subscribeNext:^(id x){
     NSLog(@"%@", x);
     }];

上面代碼如果按步驟來:

     RACSignal *usernameSourceSignal =
     self.usernameTextField.rac_textSignal;

     RACSignal *filteredUsername = [usernameSourceSignal
     filter:^BOOL(id value){
         NSString*text = value;
         return text.length > 3;
   }];

     [filteredUsername subscribeNext:^(id x){
       NSLog(@"%@", x);
     }];
  • 在管道中添加map:
    這里的 map 操作之后的步驟收到的都是NSNumber實例。
    可以使用map操作來把接收的數(shù)據(jù)轉(zhuǎn)換成想要的類型,只要它是
    對象
    。**

     [[[self.usernameTextField.rac_textSignal
      map:^id(NSString*text){
          return @(text.length);
      }]
     filter:^BOOL(NSNumber*length){
         return[length integerValue] > 3;
     }]
    subscribeNext:^(id x){
        NSLog(@"%@", x);
    }];
    

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

結(jié)尾:

簡明語法入門,圖文并茂:
http://www.teehanlax.com/blog/reactivecocoa/
參考:
http://benbeng.leanote.com/post/ReactiveCocoaTutorial-part1

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

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

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