一,取代代理:
場景:比如說在導(dǎo)航欄下有page1controller和page2controller,在page2controller 上的一個btn被點擊的時候向上傳遞告訴page1controller
那么需要如下代碼:
1,在page2controller的.h中定義如下RACSubject,暴漏給page1控制器:
@property (nonatomic, strong) RACSubject *subject;
2,page2controller的.m文件中懶加載RACSubject,并在點擊按鈕的時候發(fā)送信號數(shù)據(jù),如下:
@implementation IMPage2ViewController
#pragma mark- lazy
- (RACSubject *)subject{
if (_subject == nil) {
_subject = [RACSubject subject];
}
return _subject;
}
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)btnDidClicked:(id)sender {
[self.subject sendNext:@"controller2向1傳遞數(shù)據(jù)"];
}
@end
3,在page1控制器中,通過prepareForSegue方法來訂閱來自page2控制器的信號,如下:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
[super prepareForSegue:segue sender:sender];
IMPage2ViewController *page2Controller = segue.destinationViewController;
[page2Controller.subject subscribeNext:^(id x) {
NSLog(@"接收到數(shù)據(jù),數(shù)據(jù)內(nèi)容是:%@",x);
}];
}
注意:
另外如果不需要傳遞數(shù)據(jù)的情況下,只傳遞點擊事件的時候這種方式還可以簡化成一句代碼:
上面1,2步驟中rac的所有代碼均可以省略,只需要在page1控制器中監(jiān)聽page2控制器按鈕點擊方法然后轉(zhuǎn)化成信號,直接添加訂閱即可,如下:
1,在page2controller的.h中不用定義如下RACSubject,但是需要把點擊事件方法暴漏給page1控制器:
//這里可以直接省略
//@property (nonatomic, strong) RACSubject *subject;
- (IBAction)btnDidClicked:(id)sender ;
2,page2controller的.m文件中也就不用懶加載RACSubject
@implementation IMPage2ViewController
#pragma mark- lazy
/*
- (RACSubject *)subject{
if (_subject == nil) {
_subject = [RACSubject subject];
}
return _subject;
}
*/
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)btnDidClicked:(id)sender {
//這里只需要把方法實現(xiàn)一下即可,無需任何rac代碼,但是需要把該方法在.h文件中暴漏出去
//[self.subject sendNext:@"controller2向1傳遞數(shù)據(jù)"];
}
@end
3,在page1控制器中,通過prepareForSegue方法來訂閱來自page2控制器的信號,如下:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
[super prepareForSegue:segue sender:sender];
IMPage2ViewController *page2Controller = segue.destinationViewController;
//方式二,不需要傳遞數(shù)據(jù),只需要傳遞點擊事件
[[page2Controller rac_signalForSelector:@selector(btnDidClicked:)] subscribeNext:^(id x) {
NSLog(@"利用方式二方式進(jìn)行監(jiān)聽事件點擊,方式二方便但是不能進(jìn)行數(shù)據(jù)傳遞");
}];
}
二,取代KVO
系統(tǒng)KVO是通過監(jiān)聽屬性改變,然后調(diào)用代理方法進(jìn)行告知,如果說一個控制器需要監(jiān)聽多個屬性改變,代理方法中就需要判斷屬性然后才能做出相應(yīng)的操作,而RAC代替kvo直接是用block進(jìn)行告知,可以直接在block中對屬性進(jìn)行相應(yīng)的操作,實現(xiàn)代碼的高聚合,如下:
有兩種取代方式:
1,第一種是直接監(jiān)聽,只能得到改變后的值,如下:
[[self.view rac_valuesForKeyPath:@"frame" observer:self] subscribeNext:^(id x) {
NSLog(@"監(jiān)聽到改變---%@",x);
}];
//這個改變的時候輸出結(jié)果是:NSRect: {{0, 0}, {500, 440}}
2,第二種是監(jiān)聽改變,如果option時new,得到一個元組,仍然是得不到舊值,如下
[[self.view rac_valuesAndChangesForKeyPath:@"backgroundColor" options:NSKeyValueObservingOptionOld observer:self] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
/*
//輸出結(jié)果是元組:
//如果是NSKeyValueObservingOptionNew,只有新值,如下
(
"UIExtendedSRGBColorSpace 0 0 1 1",
{
kind = 1;
new = "UIExtendedSRGBColorSpace 0 0 1 1";
}
)
*/
//如果是NSKeyValueObservingOptionOld,結(jié)果中既有舊值,又有新值,如下
/*
(
"UIExtendedSRGBColorSpace 0 0 1 1",
{
kind = 1;
old = "UIExtendedSRGBColorSpace 1 1 1 1";
}
)
*/
```
3,取代kvo高級用法:宏RACObserve
//RACObserve(<#TARGET#>, <#KEYPATH#>) 相當(dāng)于 [TARGET rac_valuesForKeyPath:<#(NSString *)#> observer:<#(NSObject *__weak)#>]
[RACObserve(self.view, backgroundColor) subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
###三,取代addTarget監(jiān)聽
* 取代監(jiān)聽事件,比如自身的一個btn,通過block取代addTarget,不需要把點擊事件相應(yīng)操作放在另外方法中,實現(xiàn)高聚合,如下:
[[_btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
NSLog(@"按鈕被點擊");
}];
###四,取代通知方法
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
###五,監(jiān)聽文本框文字改變
[[_textField rac_textSignal] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
//監(jiān)聽文字改變的高級宏用法(可以直接把監(jiān)聽到文字改變賦值給另外的控件)
RAC(self.label, text) = _textField.rac_textSignal;
}