原文:http://www.jianshu.com/p/ff79a5ae0353
什麼是RAC?
幾乎每一篇介紹RAC的文章開頭都是這麼一個問題。我這篇文章是寫給新手(包括我自己)看的,是以這個問題更是無法忽視。
簡單的說,RAC就是一個第三方庫,他可以大大簡化你的代碼過程。
官方的說,ReactiveCocoa(其簡稱為RAC)是由GitHub開源的一個應用于iOS和OS X開發的新架構。RAC具有函數式程式設計和響應式程式設計的特性。
為什麼我們要學習RAC?
為了提高我們的開發效率。RAC在某些特定情況下開發時可以大大簡化代碼,并且目前來看安全可靠。
配置RAC環境
我習慣用cocoapods來安裝github上得開源庫,不會的新手iOS開發者有興趣可以去學一下。
想學習cocoapods的同學推薦唐巧前輩的文章。
platform:ios, '8.0'
pod 'ReactiveCocoa','~>2.1.8'
這裡有一點要注意下就是RAC的版本問題,由于還沒學習Swift,是以我是用OC編寫程式的,最新版的RAC已經支援Swift了,但是在OC的程式安裝最新版的RAC可能跑不起來,是以推薦大家使用2.5.0版本以下的RAC(具體支援Swift的版本可能有誤,但我引用的2.1.8肯定是沒問題的)。
使用RAC
1.target-action
RAC最基本的入門使用技巧就是對事件的監聽。
PS:在iOS開發中,我們所說的點選事件其實就是target-action,接觸過iOS開發的人都不會陌生UIControlEventTouchUpInside,這就是按下并松開的動作。不僅僅是UIButton,還有UITextField也有目标-動作模式。
使用前别忘了引用頭檔案~
#import <ReactiveCocoa/ReactiveCocoa.h>
接下來就是最關鍵的RAC代碼了。
[[self.textFild rac_signalForControlEvents:UIControlEventEditingChanged] subscribeNext:^(id x){
NSLog(@"change");
}];
就這麼短短的兩行代碼。他實作了一個功能,即監聽了textFild的UIControlEventEditingChanged事件,當事件發生時實作方法
NSLog
。
是以我們就可以以這段代碼為模闆進行RAC的使用,舉一反三,以後的UIButton點選事件我們都可以用RAC方法進行添加,再也不用
add Target
了。
對于textFild的文字更改監聽也有更簡單的寫法
[[self.textFild rac_textSignal] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
這樣就是每次改變TextFild都輸出改變後的結果。
再比如給我們的某個label添加一個手勢動作,我們也可以用簡單的RAC代碼完成
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] init];
[[tap rac_gestureSignal] subscribeNext:^(id x) {
NSLog(@"tap");
}];
[self.view addGestureRecognizer:tap];
這段具體我就不解釋了,相信大家都能看得懂,看不懂的自己寫寫就懂了。
2.代理
用RAC寫代理是有局限的,它隻能實作傳回值為void的代理方法
首先我們要明白我們為什麼要用RAC寫代理?答:簡化代碼!是的,的确為了簡化代碼,為什麼我要再這裡強調這個,是因為在代理方法中我深深的感受到了RAC的優點。一開始我也不願意花功夫去學RAC,但是我師父給我舉了一個例子,如果一個View裡有多個AlertView,每個AlertView有很多個按鈕,每個按鈕都有自己的點選事件,我應該怎麼寫?我想了一下,不但每個按鈕需要打标記,而且每個AlertView也要打标記,然後再往代理點選事件裡加各種方法,代碼就又臭又長。那麼讓我們看看RAC怎麼寫代理方法。
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"RAC" message:@"RAC TEST" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"other", nil];
[[self rac_signalForSelector:@selector(alertView:clickedButtonAtIndex:) fromProtocol:@protocol(UIAlertViewDelegate)] subscribeNext:^(RACTuple *tuple) {
NSLog(@"%@",tuple.first);
NSLog(@"%@",tuple.second);
NSLog(@"%@",tuple.third);
}];
[alertView show];
我們來看RAC的語句。
@selector
是指這次事件監聽的方法
fromProtocol
指依賴的代理。這裡block中有一個RACTuple,他相當于是一個集合類,他下面的first,second等就是類的各個參數,我這裡點了AlertView第二個按鈕other輸出了一下。
2016-01-04 18:24:29.114 RACStudyTest[5003:388870] <UIAlertView: 0x7ff260c90c70; frame = (0 0; 0 0); layer = <CALayer: 0x7ff260c91030>>
2016-01-04 18:24:29.115 RACStudyTest[5003:388870] 1
2016-01-04 18:24:29.115 RACStudyTest[5003:388870] (null)
可以看出
tuple.second
是ButtonAtIndex中Button的序号。那麼對于上面那個我舉的例子,就可以用
switch
給各個按鈕添加方法,這樣的代碼看起來更容易了解,方面後期維護。
當然了,AlertView代理也有簡化的代碼。
[[alertView rac_buttonClickedSignal] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
這裡的x就是各個Button的序号了,可以直接應對我上述遇到的問題。
3.通知
在我們的開發中通知也是一個比較常用的功能,主要的應用場景是某個頁面進行資料重傳需要更新model但是點選傳回棧時不會重新整理傳回界面的資料,這時就可以用通知來更新另一個頁面的資料,當然我們也可以在另一個頁面的
ViewDidAppear
方法中重新整理資料,但那是題外話。
這裡寫的Demo就是我上述說的情況。
首先,在某個頁面中我們需要發出通知,這裡就是最基本的通知的寫法。發送名為postdata的通知并傳送一個數組dataArray。
NSMutableArray *dataArray = [[NSMutableArray alloc] initWithObjects:@"1", @"2", @"3", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"postData" object:dataArray];
而在接受的頁面我們需要增加觀察者并接受數組,這時我們的RAC就派上用場了。
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"postData" object:nil] subscribeNext:^(NSNotification *notification) {
NSLog(@"%@", notification.name);
NSLog(@"%@", notification.object);
}];
當這個頁面監聽到名為postdata的通知時他就會執行block中的方法,當然這裡的參數改成
id x
也是可以的,這裡用NSNotification主要是強調它的類型。讓我們看看控制台的輸出。
2016-01-04 20:10:52.274 RACStudyTest[5918:439077] postData
2016-01-04 20:10:52.275 RACStudyTest[5918:439077] (
1,
2,
3
)
可見,notification.object就是我們想要的數組,當然我們也可以傳一些model。值得一提的是,RAC中的通知不需要
remove observer
,因為在rac_add方法中他已經寫了remove。
4.KVO
RAC中得KVO大部分都是宏定義,是以代碼異常簡潔,簡單來說就是
RACObserve(TARGET, KEYPATH)
這種形式,TARGET是監聽目标,KEYPATH是要觀察的屬性值,這裡舉一個很簡單的例子,如果UIScrollView滾動則輸出success。
UIScrollView *scrolView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 200, 400)];
scrolView.contentSize = CGSizeMake(200, 800);
scrolView.backgroundColor = [UIColor greenColor];
[self.view addSubview:scrolView];
[RACObserve(scrolView, contentOffset) subscribeNext:^(id x) {
NSLog(@"success");
}];
如果你好好回顧下KVO的寫法會不會更加感歎RAC的強大呢?
總結
RAC的東西很多,但相信這篇文章給大家入門還是可以的,這裡介紹了RAC得基本使用方法,但是還有很多好用的東西比如信号都沒介紹,甚至除了subscribeNext還有subscribeComplete和subscribeError,這些都是我給自己留得坑,以後也會發文介紹給大家。
文/巴拉森(簡書作者)
原文連結:http://www.jianshu.com/p/ff79a5ae0353
著作權歸作者所有,轉載請聯系作者獲得授權,并标注“簡書作者”。
解決問題的能力很關鍵~(iOS開發交流群:219926126)