ReactiveCocoa入門教程——第二部分(轉),reactivecocoa教程
ReactiveCocoa是一個架構,它能讓你在iOS應用中使用函數響應式編程(FRP)技術。在本系列教程的第一部分中,你學到了如何將標準的動作與事件處理邏輯替換為發送事件流的訊號。你還學到了如何轉換、分割和彙總這些訊號。
在本系列教程的第二部分,你將會學到一些ReactiveCocoa的進階功能,包括:
- 另外兩個事件類型:error 和 completed
- 節流
- 線程
- 延伸
- 其他
是時候深入研究一下了。
Twitter Instant
在本教程中你將要開發的應用叫Twitter Instant(基於Google Instant的概念),這個應用能搜尋Twitter上的內容,並根據輸入即時更新搜尋結果。
這個應用的初始工程包括一些基本的UI和必須的代碼。和第一部分一樣,你需要使用CocoaPods來擷取ReactiveCocoa架構,並整合到項目中。初始工程已經包含必須的Podfile,所以開啟終端,執行下面的命令:
pod install
如果執行正確的話,你能看到和下面類似的輸出:
Analyzing dependencies Downloading dependencies Using ReactiveCocoa (2.1.8) Generating Pods project Integrating client project
這會產生一個Xcode workspcae,TwitterInstant.xcworkspace 。在Xcode中開啟它,確認其中包含兩個項目:
- TwitterInstant :應用的邏輯就在這裡。
- Pods :這裡是外部依賴。目前只包含ReactiveCocoa。
構建運行,就能看到下面的介面:
花一些時間來熟悉應用的代碼。這個是一個很簡單的應用,基於split view controller。左欄是RWSearchFormViewController,它通過storyboard在上面添加了一些UI控制項,通過outlet串連了search text field。右欄是RWSearchResultsViewController,目前只是UITableViewController的子類。
開啟RWSearchFormViewController.m,能看到在viewDidLoad方法中,首先定位到results view controller,然後把它分配給resultsViewController私人屬性。應用的主要邏輯都會集中在RWSearchFormViewController,這個屬效能把搜尋結果提供給RWSearchResultsViewController。
驗證搜尋文本的有效性
首先要做的就是驗證搜尋文本,來確保文本長度大於2個字元。如果你完成了本系列教程的第一部分,那這個應該很熟悉。
在RWSearchFormViewController.m中的viewDidLoad 下面添加下面的方法:
- (BOOL)isValidSearchText:(NSString *)text { return text.length > 2;}
這個方法就只是確保要搜尋的字串長度大於2個字元。這個邏輯很簡單,你可能會問“為什麼要在工程檔案中寫這麼一個單獨的方法呢?”。
目前驗證輸入有效性的邏輯的確很簡單,但如果將來邏輯需要變得更複雜呢?如果是像上面的例子中那樣,那你就只需要修改一個地方。而且這樣寫能讓你代碼的可讀性更高,代碼本身就說明了你為什麼要檢查字串的長度。
在RWSearchFormViewController.m的最上面,引入ReactiveCocoa:
#import <ReactiveCocoa.h>
把下面的代碼加到viewDidLoad的最下面 :
[[self.searchText.rac_textSignal map:^id(NSString *text) { return [self isValidSearchText:text] ? [UIColor whiteColor] : [UIColor yellowColor]; }] subscribeNext:^(UIColor *color) { self.searchText.backgroundColor = color; }];
上面的代碼做了什麼呢?
- 擷取search text field 的text signal
- 將其轉換為顏色來標示輸入是否有效
- 然後在subscribeNext:block裡將顏色應用到search text field的backgroundColor屬性
構建運行,觀察在輸入文本過短時,text field的背景會變成黃色來標示輸入無效。
用圖形來表示的話,流程和下面的類似:
當text field中的文字每次發生變化時,rac_textSignal都會發送一個next 事件,事件包含當前text field中的文字。map這一步將文本值轉換成了顏色值,所以subscribeNext:這一步會拿到這個顏色值,並應用在text field的背景色上。
你應該還記得本系列教程第一部分裡這些內容吧?如果忘了,建議你先停在這裡,回去看一下第一部分。
在添加Twitter搜尋邏輯之前,還有一些有意思的話題要說說。
記憶體管理
看一下你添加到TwitterInstant中的代碼,你是否好奇建立的這些管道是如何持有的呢?顯然,它並沒有分配給某個變數或是屬性,所以它也不會有引用計數的增加,那它是怎麼銷毀的呢?
ReactiveCocoa設計的一個目標就是支援匿名產生管道這種編程風格。到目前為止,在你所寫的所有響應式代碼中,這應該是很直觀的。
為了支援這種模型,ReactiveCocoa自己持有全域的所有訊號。如果一個signal有一個或多個訂閱者,那這個signal就是活躍的。如果所有的訂閱者都被移除了,那這個訊號就能被銷毀了。