ReactivieCocoa的底層就不說明了。這里就簡單介紹它的幾個基本使用場景。
Cocoapods導入ReactiveCocoa5.0以上版本注意事項
1、如果你使用的是純swift工程,podfile文件描述如下:
use_frameworks! target '工程名稱' do pod 'ReactiveCocoa', '5.0.0-alpha.3' end
2、如果你使用的是純oc工程,podfile文件描述如下:
use_frameworks! target '工程名稱' do pod 'ReactiveObjC', '~> 2.1.0' end
3、如果你使用oc與swift混合編程,podfile文件描述如下:
use_frameworks! target '工程名稱' do pod 'ReactiveObjC', '~> 2.1.0' pod 'ReactiveCocoa', '5.0.0-alpha.3' end
基本使用
#import <ReactiveObjC/ReactiveObjC.h>
一、替代代理,代碼就是這么的簡單,如果傳遞多個值的話 x是一個RACTuple(元組)對象,這個對象在下面說明,如果值傳一個值,那么傳的是什么對象,x就是什么對象。
//redView 是在控制器view的子視圖,在redView中響應一個事件,把需要的消息從redView傳遞到控制器過來 //這段代碼是在控制器viewController.m中訂閱redView的btnClick事件消息 //如果傳遞多個值的話 x是一個RACTuple(元組)對象,比如@selector(clickWithValue1:value2:) [[_redVeiw rac_signalForSelector:@selector(btnClick:)] subscribeNext:^(id _Nullable x) { NSLog(@"x:%@",x); }];
二、代替KVO
/** 用法和原生代碼基本一致valuesForKeyPath: observer: self 是viewController age 是self的一個屬性 @param x 是age改變后的值 */ [[self rac_valuesForKeyPath:@"age" observer:nil] subscribeNext:^(id _Nullable x) { NSLog(@"x ::%@",x); }];
三、事件監聽
//_btn 是一個按鈕,給按鈕添加一個事件。不需要像原生那樣addTarget:action:forControlEvents:,然后再寫一個方法給action這么麻煩了。 [[_btn rac_signalForControlEvents:UIControlEventTouchUpInside]subscribeNext:^(__kindof UIControl * _Nullable x) { NSLog(@"x:::%@",x); }];
四、代替通知
//這個用法就和系統一樣了,只是把監聽處理的代碼聚合在一起,不需要另外寫一個方法,提高代碼閱讀性。 //我這里是監聽了一個鍵盤彈起的一個通知。 [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(NSNotification * _Nullable x) { NSLog(@"鍵盤起來了:%@",x); }];
五、輸入框改變監聽
//這個使用方式和給按鈕添加事件監聽差不多。這里ControlEvents不需要填了,監聽textField的text的改變 [_textfield.rac_textSignal subscribeNext:^(NSString * _Nullable x) { NSLog(@"textfield改變了:%@",x); }];
六、處理幾個信號完成后統一處理事件。 比如說:我們在一個界面有幾個不同的網絡數據請求,我們需要監聽他們都請求完成后才處理一些事情,那么就可以使用以下方式。
//創建信號1 RACSignal * signalA = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) { //處理信號 。。 正在發送請求1.。 /* 網絡請求代碼。。。 */ //請求完成后,發送數據 [subscriber sendNext:@"請求1完成"]; return nil; }]; //創建信號2 RACSignal * signalB = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) { //處理信號 。。 正在發送請求2.。 /* 網絡請求代碼。。。 */ //請求完成后,發送數據 [subscriber sendNext:@"請求2完成"]; return nil; }]; //監聽 signalA 和 signalB 兩個信號都完成了才調用request1WithContent:request2WithContent: //注意request1WithContent:request2WithContent:是自己寫的一個方法,但是這個方法有個原則,就是有幾個信號,就對應傳遞幾個值,不可以多,也不可以少,否則運行的時候就會崩潰,報方法錯誤(參數錯誤) [self rac_liftSelector:@selector(request1WithContent:request2WithContent:) withSignalsFromArray:@[signalA,signalB]];
/** 請求1和請求都完成了 */ -(void)request1WithContent:(NSString *)content1 request2WithContent:(NSString *)content2{ NSLog(@"請求1內容:%@",content1); NSLog(@"請求2內容:%@",content2); }
七、RACTuple元組對象,在第一步代替代理的時候提及過。元組對象和我們的數組對象差不多,使用方法也比較簡單,RAC提供了幾個宏來創建以及解包。
/** 元組 */ RACTuple * tuple = RACTuplePack(@1,@2,@3);//使用RACTuplePack宏來快速創建 NSLog(@"TUPLE:%@",tuple); //使用RACTupleUnpack宏快速解包 RACTupleUnpack(NSNumber *num1,NSNumber *num2,NSNumber *num3) = tuple; NSLog(@"num1:%@",num1); NSLog(@"num2:%@",num2); NSLog(@"num3:%@",num3); //使用下標的方式來獲取 NSLog(@"第0個:%@",tuple[0]);
上面介紹了 RACTuplePack 和 RACTupleUnpack 兩個宏的使用,下面再介紹幾個常用的宏:
1、RAC 綁定一個信號
//1、RAC 把一個對象的摸個屬性綁定一個信號,只有發出信號,就會吧信號的內容給對象的屬性賦值。 //這里吧label的text屬性綁定到textField改變信號中,textfield的內容發生改變的時候就會發出信號,label的text就會跟隨着改變。 RAC(self.label,text) = _textfield.rac_textSignal;
2、RACObserve 相當於kvo使用
//2、KVO /** @param self 是viewController @param age self的一個屬性 */ [RACObserve(self, age) subscribeNext:^(id _Nullable x) { NSLog(@"x:%@",x); }];
3、@weakify 和@strongify 這個就是為了解決在使用block的時候強引用問題,注意這兩個宏是配套使用才有效。
//3、把一個對象轉換成弱指針 @weakify(self);//self 是viewController 在block外面使用@weakify self.signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) { //在block里面再使用@strongify @strongify(self); NSLog(@"%@,",self.view); return nil; }];