1.ReactiveCocoa簡介
ReactiveCocoa(簡稱為RAC),是由Github開源的一個應(yīng)用于iOS和OS開發(fā)的新框架,Cocoa是蘋果整套框架的簡稱昨凡,因此很多蘋果框架喜歡以Cocoa結(jié)尾。
2.ReactiveCocoa作用
在我們iOS開發(fā)過程中攒暇,當(dāng)某些事件響應(yīng)的時候土匀,需要處理某些業(yè)務(wù)邏輯,這些事件都用不同的方式來處理。
比如按鈕的點擊使用action形用,ScrollView滾動使用delegate就轧,屬性值改變使用KVO等系統(tǒng)提供的方式证杭。
其實這些事件,都可以通過RAC處理
ReactiveCocoa為事件提供了很多處理方法妒御,而且利用RAC處理事件很方便解愤,可以把要處理的事情,和監(jiān)聽的事情的代碼放在一起乎莉,這樣非常方便我們管理送讲,就不需要跳到對應(yīng)的方法里。非常符合我們開發(fā)中高聚合惋啃,低耦合的思想
在RAC中最核心的類RACSiganl
RACSubscriber
:表示訂閱者的意思哼鬓,用于發(fā)送信號,這是一個協(xié)議边灭,不是一個類异希,只要遵守這個協(xié)議,并且實現(xiàn)方法才能成為訂閱者绒瘦。通過create創(chuàng)建的信號称簿,都有一個訂閱者,幫助他發(fā)送數(shù)據(jù)
//RACSignal信號使用步驟:1:創(chuàng)建信號 2:訂閱信號 3: 發(fā)送信號
//1:創(chuàng)建信號
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//didSubscribe調(diào)用:只有被訂閱了惰帽,才調(diào)用
//didSubscribe作用:發(fā)送數(shù)據(jù)
//3:發(fā)送信號
[subscriber sendNext:@1];
return nil;
}];
//2:訂閱信號
[signal subscribeNext:^(id x) {
//nextBlock調(diào)用:只有發(fā)送數(shù)據(jù)了才會調(diào)用
//nextBlock作用:接受數(shù)據(jù)憨降,展示UI
NSLog(@"%@",x);
}];
```
```RACDisposable```: 用于取消訂閱或者清理資源,當(dāng)信號發(fā)送完成或者發(fā)送錯誤的時候该酗,就會自動觸發(fā)它授药。
--不想監(jiān)聽某個信號時,可以通過它主動取消訂閱信號垂涯。
```objc
-(void)racWithSignalDisposable{
//1:創(chuàng)建信號
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
_subscriber = subscriber;
//3發(fā)送信號
[subscriber sendNext:@1];
return [RACDisposable disposableWithBlock:^{
NSLog(@"取消訂閱");
}];
}];
//2:訂閱信號
RACDisposable *disposable = [signal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
//主要訂閱者在就不會取消訂閱者
[disposable dispose];
}
```
```RACSubject:RACSubject:``` 信號提供者烁焙,自己可以充當(dāng)信號航邢,又能發(fā)送信號耕赘。
使用場景:通常用來代替代理,有了它膳殷,就不必要定義代理了操骡。
```objc
-(RACSubject *)subject{
if (_subject == nil) {
_subject = [RACSubject subject];
}
return _subject;
}
-(IBAction)clickBtn:(UIButton *)btn{
[self.subject sendNext:@1];
}
-(void)racWithDelegate{
//訂閱
[_redView.subject subscribeNext:^(id x) {
NSLog(@"控制器做了一件事情%@",x);
}];
}
```
```RACTuple```: 元組類,類似NSArray,用來包裝值.
```objc
-(void)racWtihTuple{
//rac集合
RACTuple *tuple = [RACTuple tupleWithObjectsFromArray:@[@"123",@"234",@1]];
//取出rac集合中的第0個元素
NSString *str = tuple[0];
NSLog(@"%@",str);
}
```
```RACSequence``` :RAC中的集合類,用于代替NSArray,NSDictionary,可以使用它來快速遍歷數(shù)組和字典赚窃。
```objc
-(void)racWithAarray{
//rac遍歷數(shù)組
//創(chuàng)建一個數(shù)組
NSArray *arry = @[@"123",@"321",@"111"];
//把數(shù)組轉(zhuǎn)變?yōu)橐粋€集合
RACSequence *sequence = arry.rac_sequence;
//把集合轉(zhuǎn)換為一個信號
RACSignal *singnal = sequence.signal;
//使用信號訂閱信息
[singnal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
[arry.rac_sequence.signal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
}
```
實例:
```objc
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
self.person.userName = [NSString stringWithFormat:@"zhangsan---%u",arc4random_uniform(100)];
}
//rac實現(xiàn)kvo
-(void)racWithKvo{
[RACObserve(self.person, userName) subscribeNext:^(id x) {
self.nameLabel.text = x;
}];
}
[_accountTextFiled.rac_textSignal subscribeNext:^(id x) {
self.nameLabel.text = x;
}];
```
#多個輸入文件作為信號源
多用于登陸等業(yè)務(wù)需求
```objc
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px 'PingFang SC'; color: #4cbf57}p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #ffffff}p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #ffffff; min-height: 13.0px}p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #93c86a}p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #4cbf57}span.s1 {font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures}span.s2 {font-variant-ligatures: no-common-ligatures}span.s3 {font-variant-ligatures: no-common-ligatures; color: #c2349b}span.s4 {font-variant-ligatures: no-common-ligatures; color: #ffffff}span.s5 {font-variant-ligatures: no-common-ligatures; color: #00afca}span.s6 {font-variant-ligatures: no-common-ligatures; color: #8b84cf}span.s7 {font: 11.0px 'PingFang SC'; font-variant-ligatures: no-common-ligatures}span.s8 {font-variant-ligatures: no-common-ligatures; color: #93c86a}span.s9 {font-variant-ligatures: no-common-ligatures; color: #e44448}
//多個文本框輸入信號組合使用
-(void)racTextFiledsDemo{
RACSignal *nameSignal = [self.nameTextFiled rac_textSignal];
RACSignal *pwdSignal = [self.pwdTextFiled rac_textSignal];
NSArray *signals = @[nameSignal,pwdSignal];
//訂閱信號
[[RACSignal combineLatest:signals]subscribeNext:^(RACTuple *x) {
NSString *name = x.first;
NSString *pawd = x.second;
NSLog(@"%@%@",x,name);
if (name.length>0 && pawd.length>0) {
self.photoImageView.image = [UIImage imageNamed:@"Demo"];
}else if(name.length >0 || pawd.length > 0){
self.photoImageView.image = [UIImage imageNamed:@"Demo1"];
}
}];
}
```
#rac_signalForSelector的使用册招,代替代理(不需要傳值的情況下)
```objc
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #4cbf57}p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #93c86a}p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #ffffff; min-height: 13.0px}p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #ffffff}span.s1 {font-variant-ligatures: no-common-ligatures; color: #ffffff}span.s2 {font-variant-ligatures: no-common-ligatures}span.s3 {font: 11.0px 'PingFang SC'; font-variant-ligatures: no-common-ligatures}span.s4 {font-variant-ligatures: no-common-ligatures; color: #c2349b}span.s5 {font-variant-ligatures: no-common-ligatures; color: #00afca}span.s6 {font-variant-ligatures: no-common-ligatures; color: #e44448}span.s7 {font-variant-ligatures: no-common-ligatures; color: #93c86a}
//rac_signalForSelector:監(jiān)聽某對象有沒有調(diào)用某方法
[[self.readView rac_signalForSelector:@selector(clickBtn:)] subscribeNext:^(id x) {
NSLog(@"clickBtn");
}];
[[self rac_signalForSelector:@selector(didReceiveMemoryWarning)] subscribeNext:^(id x) {
NSLog(@"clickBtn");
}];
```
```objc
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #ffffff}p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #ffffff; min-height: 13.0px}span.s1 {font-variant-ligatures: no-common-ligatures}span.s2 {font-variant-ligatures: no-common-ligatures; color: #c2349b}
@weakify(self)
[RACObserve(self.person, name) subscribeNext:^(id x) {
@strongify(self)
```
#全部代碼
```objc
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #ffffff}p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #ffffff; min-height: 13.0px}p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #e44448}p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #4cbf57}p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #93c86a}p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px 'PingFang SC'; color: #4cbf57}p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #00afca}span.s1 {font-variant-ligatures: no-common-ligatures}span.s2 {font-variant-ligatures: no-common-ligatures; color: #c2349b}span.s3 {font-variant-ligatures: no-common-ligatures; color: #ffffff}span.s4 {font-variant-ligatures: no-common-ligatures; color: #00afca}span.s5 {font: 11.0px 'PingFang SC'; font-variant-ligatures: no-common-ligatures}span.s6 {font-variant-ligatures: no-common-ligatures; color: #e44448}span.s7 {font-variant-ligatures: no-common-ligatures; color: #93c86a}span.s8 {font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures}span.s9 {font-variant-ligatures: no-common-ligatures; color: #8b84cf}span.s10 {font: 11.0px 'PingFang SC'; font-variant-ligatures: no-common-ligatures; color: #e44448}span.s11 {font-variant-ligatures: no-common-ligatures; color: #d28f5a}span.s12 {font-variant-ligatures: no-common-ligatures; color: #4cbf57}span.s13 {font: 11.0px 'PingFang SC'; font-variant-ligatures: no-common-ligatures; color: #4cbf57}
}
-(void)dealloc{
NSLog(@"viewController dealloc");
}
//rac代替代理
-(void)racWithDelegate{
// 1:rac的subject 2:rac的select
//rac_signalForSelector:監(jiān)聽某對象有沒有調(diào)用某方法
[[self.readView rac_signalForSelector:@selector(clickBtn:)] subscribeNext:^(id x) {
NSLog(@"clickBtn");
}];
[[self rac_signalForSelector:@selector(didReceiveMemoryWarning)] subscribeNext:^(id x) {
NSLog(@"clickBtn");
}];
}
//多個文本框輸入信號組合使用
-(void)racTextFiledsDemo{
RACSignal *nameSignal = [self.nameTextFiled rac_textSignal];
RACSignal *pwdSignal = [self.pwdTextFiled rac_textSignal];
NSArray *signals = @[nameSignal,pwdSignal];
//訂閱信號
[[RACSignal combineLatest:signals]subscribeNext:^(RACTuple *x) {
NSString *name = x.first;
NSString *pawd = x.second;
NSLog(@"%@%@",x,name);
if (name.length>0 && pawd.length>0) {
self.photoImageView.image = [UIImage imageNamed:@"Demo"];
}else if(name.length >0 || pawd.length > 0){
self.photoImageView.image = [UIImage imageNamed:@"Demo1"];
}
}];
}
//rac及時刷新UI
-(void)racWithUI{
[_nameTextFiled.rac_textSignal subscribeNext:^(id x) {
self.nameLabel.text = x;
}];
}
//rRAC中的集合類,用于代替NSArray,NSDictionary,可以使用它來快速遍歷數(shù)組和字典。
-(void)racWithSeq{
NSArray *array = @[@"7",@"3",@"4",@"5"];
// //把數(shù)組轉(zhuǎn)為一個集合
// RACSequence *sequence = array.rac_sequence;
//
// //把集合轉(zhuǎn)為一個信號
// RACSignal *signal = sequence.signal;
//
// //使用訂閱者訂閱信號
// [signal subscribeNext:^(id x) {
//
// NSLog(@"%@",x);
// }];
[array.rac_sequence.signal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
self.person.name = [NSString stringWithFormat:@"liuYAHUA---%u",arc4random_uniform(100)];
}
//rac中的kvo
-(void)racWithKvo{
@weakify(self)
//觀察person的name屬性
[RACObserve(self.person, name) subscribeNext:^(id x) {
@strongify(self)
self.nameLabel.text = x;
}];
}
//rac中訂閱者的取消
-(void)racWithSignalDisposable{
//rac中最核心的就是信號 1:創(chuàng)建信號 2:訂閱信號 3:發(fā)送信號
//1:創(chuàng)建信號
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//didSubscribe調(diào)用:只有被訂閱了勒极,才會調(diào)用
//didSubscribe作用:發(fā)送數(shù)據(jù)
_subscriber = subscriber;
//3:發(fā)送信號
[subscriber sendNext:@"劉亞華"];
return [RACDisposable disposableWithBlock:^{
NSLog(@"劉亞華被取消了");
}];
}];
//2:訂閱信號
RACDisposable *disposable = [signal subscribeNext:^(id x) {
//nextBlock調(diào)用:只有發(fā)送了數(shù)據(jù)才會調(diào)用
//nextBlock作用:接受數(shù)據(jù)是掰,展示UI
NSLog(@"%@",x);
}];
//取消
[disposable dispose];
}
-(void)racWithSignal{
//rac中最核心的就是信號 1:創(chuàng)建信號 2:訂閱信號 3:發(fā)送信號
//1:創(chuàng)建信號
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//didSubscribe調(diào)用:只有被訂閱了,才會調(diào)用
//didSubscribe作用:發(fā)送數(shù)據(jù)
//3:發(fā)送信號
[subscriber sendNext:@"劉亞華"];
return nil;
}];
//2:訂閱信號
[signal subscribeNext:^(id x) {
//nextBlock調(diào)用:只有發(fā)送了數(shù)據(jù)才會調(diào)用
//nextBlock作用:接受數(shù)據(jù)辱匿,展示UI
NSLog(@"%@",x);
}];
}
```
#鏈?zhǔn)骄幊?
```objc
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #ffffff}p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #ffffff; min-height: 13.0px}span.s1 {font-variant-ligatures: no-common-ligatures}span.s2 {font-variant-ligatures: no-common-ligatures; color: #c2349b}span.s3 {font-variant-ligatures: no-common-ligatures; color: #00afca}span.s4 {font-variant-ligatures: no-common-ligatures; color: #e44448}span.s5 {font-variant-ligatures: no-common-ligatures; color: #93c86a}
-(void)run{
NSLog(@"run");
}
-(void)play{
NSLog(@"play");
}
-(Person *(^)(CGFloat))run1{
return ^(CGFloat DIS){
NSLog(@"run1%f",DIS);
return self;
};
}
-(Person *(^)(NSString *))play1{
return ^(NSString *qiu){
NSLog(@"play1%@",qiu);
return self;
};
}
```