公司開發在使用RAC,之前居然一直沒有了解過,獨立開發的弊端,資訊閉塞,而且自己也懶,這幾天看了下RAC,确實很強大有木有。
什麼是ARC
簡單的說,RAC就是一個第三方庫,他可以大大簡化你的代碼過程。
官方的說,ReactiveCocoa(其簡稱為RAC)是由GitHub開源的一個應用于iOS和OS X開發的新架構。RAC具有函數式程式設計和響應式程式設計的特性。
為什麼我們要學習RAC?
為了提高我們的開發效率。RAC在某些特定情況下開發時可以大大簡化代碼,并且目前來看安全可靠。
配置RAC環境
我習慣用cocoapods來安裝github上得開源庫,推薦大家使用2.5.0版本以下的RAC
1 platform :ios, ‘8.0’
2 target “RAC-Text” do
3
4 pod 'ReactiveCocoa', '~> 2.5'
5
6 end
信号signal是RAC的絕對核心,所有的操作都是圍繞着信号來處理的。
比如:建立信号,訂閱信号,發送信号是消息發送的核心步驟。
常見的三個信号類為:
- RACSignal
- RACSubject
- RACReplaySubject
RACSiganl:信号類,一般表示将來有資料傳遞,隻要有資料改變,信号内部接收到資料,就會馬上發出資料。
ReactiveCocoa開發中常見用法
1 代替代理.
rac_signalForSelector:
用于替代代理。
首先要說的:用RAC寫代理是有局限的,它隻能實作傳回值為void的代理方法
1 UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"RAC" message:@"RAC TEST" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"other", nil];
2 [[self rac_signalForSelector:@selector(alertView:clickedButtonAtIndex:) fromProtocol:@protocol(UIAlertViewDelegate)] subscribeNext:^(RACTuple *tuple) {
3 NSLog(@"%@",tuple.first);
4 NSLog(@"%@",tuple.second);
5 NSLog(@"%@",tuple.third);
6 }];
7 [alertView show];
我們來看RAC的語句。
@selector
是指這次事件監聽的方法
fromProtocol
指依賴的代理。這裡block中有一個RACTuple,他相當于是一個集合類,他下面的first,second等就是類的各個參數,我這裡點了AlertView第二個按鈕other輸出了一下。
1 2016-01-04 18:24:29.114 RACStudyTest[5003:388870] <UIAlertView: 0x7ff260c90c70; frame = (0 0; 0 0); layer = <CALayer: 0x7ff260c91030>>
2 2016-01-04 18:24:29.115 RACStudyTest[5003:388870] 1
3 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的序号了,可以直接應對我上述遇到的問題。
2代替KVO :
rac_valuesAndChangesForKeyPath:
用于監聽某個對象的屬性改變。
RAC中得KVO大部分都是宏定義,是以代碼異常簡潔,簡單來說就是
RACObserve(TARGET, KEYPATH)
這種形式,TARGET是監聽目标,KEYPATH是要觀察的屬性值,這裡舉一個很簡單的例子,如果UIScrollView滾動則輸出success。
1 UIScrollView *scrolView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 200, 400)];
2 scrolView.contentSize = CGSizeMake(200, 800);
3 scrolView.backgroundColor = [UIColor greenColor];
4 [self.view addSubview:scrolView];
5 [RACObserve(scrolView, contentOffset) subscribeNext:^(id x) {
6 NSLog(@"success");
7 }];
3 監聽事件:
rac_signalForControlEvents:
用于監聽某個事件。
1 // 把按鈕點選事件轉換為信号,點選按鈕,就會發送信号
2 [[self.btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
3 NSLog(@"按鈕被點選了");
4 }];
給Lable或者View添加監聽
1 UILabel *textLab = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 200, 30)]; 2 textLab.backgroundColor = [UIColor greenColor]; 3 textLab.text = @"********************"; 4 textLab.userInteractionEnabled = YES; 5 [self.view addSubview:textLab]; 6 7 8 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] init]; 9 [[tap rac_gestureSignal] subscribeNext:^(id x) { 10 NSLog(@"點選Lab"); 11 }]; 12 [textLab addGestureRecognizer:tap];
點選lab控制台會輸出 :點選Lab
4 代替通知:
rac_addObserverForName:
用于監聽某個通知。
在我們的開發中通知也是一個比較常用的功能,主要的應用場景是某個頁面進行資料重傳需要更新model但是點選傳回棧時不會重新整理傳回界面的資料,這時就可以用通知來更新另一個頁面的資料
首先,在某個頁面中我們需要發出通知,這裡就是最基本的通知的寫法。發送名為postdata的通知并傳送一個數組dataArray
1 NSMutableArray *dataArray = [[NSMutableArray alloc] initWithObjects:@"1", @"2", @"3", nil];
2 [[NSNotificationCenter defaultCenter] postNotificationName:@"postData" object:dataArray];
而在接受的頁面我們需要增加觀察者并接受數組,這時我們的RAC就派上用場了。
1 [[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"postData" object:nil] subscribeNext:^(NSNotification *notification) {
2 NSLog(@"%@", notification.name);
3 NSLog(@"%@", notification.object);
4 }];
當這個頁面監聽到名為postdata的通知時他就會執行block中的方法,當然這裡的參數改成
id x
也是可以的,這裡用NSNotification主要是強調它的類型。讓我們看看控制台的輸出
1 2016-01-04 20:10:52.274 RACStudyTest[5918:439077] postData
2 2016-01-04 20:10:52.275 RACStudyTest[5918:439077] (
3 1,
4 2,
5 3
6 )
可見,notification.object就是我們想要的數組,當然我們也可以傳一些model。值得一提的是,RAC中的通知不需要
remove observer
,因為在rac_add方法中他已經寫了remove。
5 監聽文本框文字改變:
rac_textSignal:
隻要文本框發出改變就會發出這個信号。
1 UITextField *text1 = [[UITextField alloc] initWithFrame:CGRectMake(100, 200, 200, 30)];
2 text1.backgroundColor = [UIColor cyanColor];
3 [self.view addSubview:text1];
4
5 [[text1 rac_textSignal] subscribeNext:^(id x) {
6 static int i = 0;
7 i++;
8 // text改變就會列印
9 NSLog(@"厲害了我的哥------ %d", i);
10 }];
6 處理當界面有多次請求時,需要都擷取到資料時,才能展示界面
rac_liftSelector:withSignalsFromArray:Signals:
當傳入的Signals(信号數組),每一個signal都至少sendNext過一次,就會去觸發第一個selector參數的方法。
使用注意:幾個信号,參數一的方法就幾個參數,每個參數對應信号發出的資料。
1 // 處理多個請求,都傳回結果的時候,統一做處理.
2 RACSignal *request1 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
3 // 發送請求1
4 [subscriber sendNext:@"發送請求1"];
5 return nil;
6 }];
7
8 RACSignal *request2 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
9 // 發送請求2
10 [subscriber sendNext:@"發送請求2"];
11 return nil;
12 }];
13
14 // 使用注意:幾個信号,參數一的方法就幾個參數,每個參數對應信号發出的資料。
15 [self rac_liftSelector:@selector(updateUIWithR1:r2:) withSignalsFromArray:@[request1,request2]];
16 }
17 // 更新UI(該方法有要求,有多少個信号就要求有多少個參數,參數的内容就是發送的資料。)
18 - (void)updateUIWithR1:(id)data r2:(id)data1
19 {
20 NSLog(@"更新UI%@,%@",data,data1);
21 }
内容來自網絡摘抄和總結
http://www.jianshu.com/p/769025368bcb
http://www.cnblogs.com/qiyer/p/5483162.html
http://www.jianshu.com/p/ff79a5ae0353
轉載于:https://www.cnblogs.com/crazygeek/p/6489696.html