最近看到好多人用到RAC,就簡單的看了一些別的大神文章,寫出來了一點
什么是RAC?
幾乎每一篇介紹RAC的文章開頭都是這么一個問題。我這篇文章是寫給新手(包括我自己)看的,所以這個問題更是無法忽視。
簡單的說,RAC就是一個第三方庫,他可以大大簡化你的代碼過程。
官方的說,ReactiveCocoa(其簡稱為RAC)是由GitHub開源的一個應用于iOS和OS X開發的新框架。RAC具有函數式編程和響應式編程的特性。
為什么我們要學習RAC?
為了提高我們的開發效率。RAC在某些特定情況下開發時可以大大簡化代碼,并且目前來看安全可靠。
配置RAC環境
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
接下來就是最關鍵的RAC代碼了。
[[self.textFildrac_signalForControlEvents:UIControlEventEditingChanged] subscribeNext:^(idx){? ? NSLog(@"change");}];
就這么短短的兩行代碼。他實現了一個功能,即監聽了textFild的UIControlEventEditingChanged事件,當事件發生時實現方法NSLog。
所以我們就可以以這段代碼為模板進行RAC的使用,舉一反三,以后的UIButton點擊事件我們都可以用RAC方法進行添加,再也不用add Target了。
對于textFild的文字更改監聽也有更簡單的寫法
[[self.textFildrac_textSignal] subscribeNext:^(idx){? ? NSLog(@"%@",x);}];
這樣就是每次改變TextFild都輸出改變后的結果。
再比如給我們的某個label添加一個手勢動作,我們也可以用簡單的RAC代碼完成
UITapGestureRecognizer*tap = [[UITapGestureRecognizeralloc] init];[[tap rac_gestureSignal] subscribeNext:^(idx) {NSLog(@"tap");}];[self.viewaddGestureRecognizer:tap];
這段具體我就不解釋了,相信大家都能看得懂,看不懂的自己寫寫就懂了。
2.代理
用RAC寫代理是有局限的,它只能實現返回值為void的代理方法
首先我們要明白我們為什么要用RAC寫代理?答:簡化代碼!是的,的確為了簡化代碼,為什么我要再這里強調這個,是因為在代理方法中我深深的感受到
了RAC的優點。一開始我也不愿意花功夫去學RAC,但是我師父給我舉了一個例子,如果一個View里有多個AlertView,每個AlertView
有很多個按鈕,每個按鈕都有自己的點擊事件,我應該怎么寫?我想了一下,不但每個按鈕需要打標記,而且每個AlertView也要打標記,然后再往代理點
擊事件里加各種方法,代碼就又臭又長。那么讓我們看看RAC怎么寫代理方法。
UIAlertView*alertView = [[UIAlertViewalloc] initWithTitle:@"RAC"message:@"RAC TEST"delegate:selfcancelButtonTitle:@"cancel"otherButtonTitles:@"other",nil];[[selfrac_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-0418:24:29.114RACStudyTest[5003:388870] >2016-01-0418:24:29.115RACStudyTest[5003:388870]12016-01-0418:24:29.115RACStudyTest[5003:388870] (null)
可以看出tuple.second是ButtonAtIndex中Button的序號。那么對于上面那個我舉的例子,就可以用switch給各個按鈕添加方法,這樣的代碼看起來更容易理解,方面后期維護。
當然了,AlertView代理也有簡化的代碼。
[[alertViewrac_buttonClickedSignal] subscribeNext:^(idx){? ? NSLog(@"%@",x);}];
這里的x就是各個Button的序號了,可以直接應對我上述遇到的問題。
3.通知
在我們的開發中通知也是一個比較常用的功能,主要的應用場景是某個頁面進行數據重傳需要更新model但是點擊返回棧時不會刷新返回界面的數據,這時就可以用通知來更新另一個頁面的數據,當然我們也可以在另一個頁面的ViewDidAppear方法中刷新數據,但那是題外話。
這里寫的Demo就是我上述說的情況。
首先,在某個頁面中我們需要發出通知,這里就是最基本的通知的寫法。發送名為postdata的通知并傳送一個數組dataArray。
NSMutableArray*dataArray = [[NSMutableArrayalloc] initWithObjects:@"1",@"2",@"3",nil];[[NSNotificationCenterdefaultCenter] postNotificationName:@"postData"object:dataArray];
而在接受的頁面我們需要增加觀察者并接受數組,這時我們的RAC就派上用場了。
[[[NSNotificationCenterdefaultCenter] rac_addObserverForName:@"postData"object:nil] subscribeNext:^(NSNotification*notification){? ? NSLog(@"%@", notification.name);NSLog(@"%@", notification.object);}];
當這個頁面監聽到名為postdata的通知時他就會執行block中的方法,當然這里的參數改成id x也是可以的,這里用NSNotification主要是強調它的類型。讓我們看看控制臺的輸出。
2016-01-0420:10:52.274RACStudyTest[5918:439077] postData2016-01-0420:10:52.275RACStudyTest[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 = [[UIScrollViewalloc] initWithFrame:CGRectMake(0,0,200,400)];scrolView.contentSize=CGSizeMake(200,800);scrolView.backgroundColor= [UIColorgreenColor];[self.viewaddSubview:scrolView];[RACObserve(scrolView, contentOffset) subscribeNext:^(idx) {NSLog(@"success");}];