一.RAC 是什么否过?能做什么?
1.RAC是Reactive Cocoa的簡(jiǎn)稱膨蛮,是一種支持函數(shù)式響應(yīng)式編程的框架叠纹,由GitHub團(tuán)隊(duì)編寫(xiě)而成。
2.RAC可以做什么呢敞葛?
RAC通過(guò)信號(hào)的方式誉察,鏈接組合和反應(yīng)。通過(guò)一個(gè)統(tǒng)一的方法來(lái)處理異步行為惹谐,包括通知(NotificationCenter)持偏、委托代理(Delegate)、目標(biāo)操作機(jī)制(AddTarget)氨肌、KVO鸿秆、回調(diào)Block。
也就是通過(guò)block的方式怎囚,來(lái)處理和簡(jiǎn)化這些異步行為卿叽。
3.版本大事件:
2.5以及之前版本不支持swift。
3.0版本ReactiveObjC是支持OC的最后一個(gè)版本恳守。
4.0版本ReactiveSwift開(kāi)始只支持swift考婴。
二.為什么用RAC? 優(yōu)缺點(diǎn)!
喜歡一個(gè)人,往往是從他身上的某個(gè)閃光點(diǎn)開(kāi)始催烘。
1.RAC有哪些閃光點(diǎn)沥阱?[需要進(jìn)一步了解]
a.簡(jiǎn)潔高效,一行代碼能解決的問(wèn)題就不要用多行了(就不能寫(xiě)半行??)
b.注冊(cè)的通知伊群,不需要釋放考杉,RAC內(nèi)部幫你做了策精。
2.缺點(diǎn)
a.高耦合性
b.需要進(jìn)一步了解
三.怎么使用ARC?
1.使用pod方式進(jìn)行安裝崇棠,GiTHub團(tuán)隊(duì)已經(jīng)將支持OC和swift的支持庫(kù)分開(kāi)了咽袜,使用OC的可以
pod 'ReactiveObjC', '~> 3.0.0'
2.引入頭文件
#import <ReactiveObjC/ReactiveObjC.h>
3.開(kāi)始進(jìn)入正題。
RAC是通過(guò)信號(hào)方式易茬,鏈接組合和反應(yīng)酬蹋。所以要有三步及老,創(chuàng)建信號(hào)抽莱、監(jiān)聽(tīng)信號(hào)、發(fā)送信號(hào)骄恶、(訂閱信號(hào))食铐。
RAC發(fā)送信號(hào)包括了三種情況,下一步該做什么僧鲁、成功之后做什么虐呻、失敗(出錯(cuò))之后該做什么寞秃。
// 創(chuàng)建信號(hào)
RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
// 發(fā)送信號(hào)斟叼,有三種情況,下一步春寿,出錯(cuò)朗涩、失敗
[subscriber sendNext:@"RAC 我來(lái)了!"];
[subscriber sendError:nil];
[subscriber sendCompleted];
return nil;
}];
// 訂閱信號(hào) (也可以分開(kāi)寫(xiě))
[signal subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
} error:^(NSError * _Nullable error) {
NSLog(@"%@",error);
} completed:^{
NSLog(@"RAC 成功到達(dá)地球");
}];
// ----------------也可以簡(jiǎn)化寫(xiě)法-----------------------
// 創(chuàng)建信號(hào)
[[RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
// 發(fā)送信號(hào)
[subscriber sendNext:@"RAC 我來(lái)了绑改!"];
return nil;
}] subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
4.避免循環(huán)引用谢床,在block內(nèi)部用self來(lái)引用控制器的成員變量, 可能會(huì)造成循環(huán)引用厘线,這個(gè)時(shí)候在“外部用@weakify识腿,內(nèi)部用@strongify”這個(gè)方式來(lái)解決,如果直接用“_”來(lái)引用成員變量造壮,可能會(huì)解決不了循環(huán)引用的問(wèn)題
//問(wèn)題:在信號(hào)中打印了控制器渡讼,也就是強(qiáng)引用了控制器,控制器中又強(qiáng)引用了信號(hào)耳璧,如下成箫,就會(huì)形成循環(huán)應(yīng)用
//信號(hào)外部用@weakify,內(nèi)部用@strongify
@weakify(self)
RACSignal *signal = [[btn rac_signalForControlEvents:UIControlEventTouchUpInside]subscr subscribeNext:^(__kindof UIControl * _Nullable x) {
@strongify(self);
self.lable.text = @"這是來(lái)自RAC的信號(hào)@懵铡N爸凇!";
}];
self.signal = signal;
4.RAC中實(shí)現(xiàn)KVO
可以通過(guò)宏RACObserve來(lái)實(shí)現(xiàn)召廷,絕壁一行代碼凳厢,替代addObserver: forKeyPath:options: context:(void *)context
RAC中強(qiáng)大的宏账胧,拿來(lái)小用一下Observe
#define RACObserve(TARGET, KEYPATH) _RACObserve(TARGET, KEYPATH)
// 當(dāng)對(duì)象self.dog的屬性nickName發(fā)生變化時(shí),就會(huì)調(diào)用這個(gè)block
[RACObserve(self.dog, nickName) subscribeNext:^(id _Nullable x) {
self.label.text = x; // x是subScribe發(fā)送的內(nèi)容
}];
5.RAC中實(shí)現(xiàn)控件的事件(addTarget)
查看源碼可以看到先紫,其實(shí)RAC寫(xiě)了一個(gè)UIControl的分類(lèi) "UIControl+RACSignalSupport.h"治泥,在分類(lèi)中完成了信號(hào)的三部曲,創(chuàng)建信號(hào)遮精、訂閱信號(hào)居夹、發(fā)布信號(hào)。
[[self.btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
NSLog(@"使用RAC添加按鈕事件1境濉W贾!");
}];
6.RAC中有關(guān)控件檬洞,比較好玩的地方狸膏,真心推薦應(yīng)該玩一下。
想用什么控件添怔,就去RAC包中去找相關(guān)的擴(kuò)展就好了湾戳,不多說(shuō),代碼走起广料。砾脑。。比如監(jiān)聽(tīng)UITextField的輸入
// 傳統(tǒng)方式監(jiān)聽(tīng)UITextField的輸入艾杏,需要很多代碼,這里不多說(shuō),
// 使用ARC是怎么玩起來(lái)的呢韧衣?好吧,開(kāi)始你的表演糜颠!別忘去哪里找汹族?
// 去RAC包中有關(guān)UITextField的擴(kuò)展,你會(huì)發(fā)現(xiàn)這個(gè)擴(kuò)展其實(shí)都叫做
// RACSignalSupport
[[self.textField rac_textSignal] subscribeNext:^(NSString * _Nullable x) {
NSLog(@"textField==>text ==>%@",x);
}];
7.同時(shí)獲取多個(gè)控件的變化其兴,在RAC中就是將多個(gè)信號(hào)合并成一個(gè)信號(hào)進(jìn)行處理顶瞒,使用+ (RACSignal *)combineLatest:(id<NSFastEnumeration>)signals
so easy!最好不要超過(guò)5個(gè)(因?yàn)橄拗屏四卦C據(jù)在下面代碼里)榴徐。
[[RACSignal combineLatest:@[self.textField.rac_textSignal,self.textField2.rac_textSignal]] subscribeNext:^(RACTuple * _Nullable x) {
NSString *name = x.first;
NSString *pwd = x.second;
NSLog(@"name===>%@,pwd===>%@",name,pwd);
}];
// --------------限制個(gè)數(shù)的證據(jù)在此--------------
typedef struct {
unsigned long state;
id __unsafe_unretained _Nullable * _Nullable itemsPtr;
unsigned long * _Nullable mutationsPtr;
unsigned long extra[5];
} NSFastEnumerationState;
// --------------限制個(gè)數(shù)的證據(jù)在此--------------
8.巧妙使用reduce,合并信號(hào)的數(shù)據(jù)匀归,進(jìn)行統(tǒng)計(jì)計(jì)算使用坑资,例如判斷手機(jī)號(hào)和密碼同時(shí)存在,才可以點(diǎn)擊登錄按鈕
[[RACSignal combineLatest:@[nameTextField.rac_textSignal, pwdTextField.rac_textSignal] reduce:^id _Nullable(NSString * name, NSString * pwd){
NSLog(@"%@ ,%@", name,pwd);
return @(name.length > 0 && pwd.length > 0);
return nil;
}] subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
_demoButton.enabled = [x boolValue];
}];
備注: 如果pod安裝穆端,遇到一下錯(cuò)誤
解決方法:在pod 'ReactiveCocoa’,’~>3.0’前面添加use_frameworks!
use_frameworks!
pod 'ReactiveCocoa’,’~>3.0’
原因:對(duì)于 Swift 項(xiàng)目袱贮,CocoaPods 提供了動(dòng)態(tài) Framework 的支持。通過(guò) use_frameworks! 選項(xiàng)控制体啰。對(duì)于 Swift 寫(xiě)的庫(kù)來(lái)說(shuō)攒巍,想通過(guò) CocoaPods 引入工程嗽仪,必須加入 use_frameworks! 選項(xiàng)。