原文:http://www.jianshu.com/p/ff79a5ae0353ios
幾乎每一篇介紹RAC的文章開頭都是這麼一個問題。我這篇文章是寫給新手(包括我本身)看的,因此這個問題更是沒法忽視。git
簡單的說,RAC就是一個第三方庫,他能夠大大簡化你的代碼過程。github
官方的說,ReactiveCocoa(其簡稱爲RAC)是由GitHub開源的一個應用於iOS和OS X開發的新框架。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確定是沒問題的)。ide
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];
這段具體我就不解釋了,相信你們都能看得懂,看不懂的本身寫寫就懂了。
用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的序號了,能夠直接應對我上述遇到的問題。
在咱們的開發中通知也是一個比較經常使用的功能,主要的應用場景是某個頁面進行數據重傳須要更新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。
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,這些都是我給本身留得坑,之後也會發文介紹給你們。