ReactiveCocoa 學(xué)習(xí)筆記 - 使用篇

1.ReactiveCocoa開發(fā)中常見用法有哪些恭取?

第1種:代替代理

rac_signalForSelector:用于替代代理

[objc]view plaincopy

//?1.代替代理,RACSubject

//?RAC方法:可以判斷下某個方法有沒有調(diào)用

//?只要self調(diào)用Selector就會產(chǎn)生一個信號

//?rac_signalForSelector:監(jiān)聽某個對象調(diào)用某個方法

[[selfrac_signalForSelector:@selector(didReceiveMemoryWarning)]subscribeNext:^(idx)?{

NSLog(@"控制器調(diào)用了didReceiveMemoryWarning");

}];

//?判斷下redView有沒有調(diào)用btnClick,就表示點擊了按鈕

[[_redViewrac_signalForSelector:@selector(btnClick:)]subscribeNext:^(idx)?{

NSLog(@"點擊了按鈕");

}];

第2種:代替KVO

rac_valuesAndChangesForKeyPath:用于監(jiān)聽某個對象的屬性改變

[objc]view plaincopy

[_redViewrac_observeKeyPath:@"name"options:NSKeyValueObservingOptionNewobserver:nilblock:^(idvalue,NSDictionary*change,BOOLcausedByDealloc,BOOLaffectedOnlyLastComponent)?{

//?只要監(jiān)聽的屬性一改變調(diào)用

NSLog(@"%@",_redView.name);

}];

//?KVO:第二種,只要對象的值改變,就會產(chǎn)生信號,訂閱信號

[[_redViewrac_valuesForKeyPath:@"name"observer:nil]subscribeNext:^(idx)?{

}];

第3種:監(jiān)聽事件

rac_signalForControlEvents:用于監(jiān)聽某個事件

[objc]view plaincopy

//??只要按鈕產(chǎn)生這個事件,就會產(chǎn)生一個信號

[[_btnrac_signalForControlEvents:UIControlEventTouchUpInside]subscribeNext:^(idx)?{

NSLog(@"按鈕被點擊%@",x);

}];

_btn.rac_command=?[[RACCommandalloc]initWithSignalBlock:^RACSignal*(idinput)?{

NSLog(@"按鈕點擊");

return[RACSignalempty];

}];

第4種:代替通知

rac_addObserverForName:用于監(jiān)聽某個通知

[objc]view plaincopy

[[[NSNotificationCenterdefaultCenter]rac_addObserverForName:UIKeyboardWillShowNotificationobject:nil]subscribeNext:^(idx)?{

NSLog(@"%@",x);

}];

第5種:監(jiān)聽文本框文字改變

rac_textSignal:只要文本框發(fā)出改變就會發(fā)出這個信號

[objc]view plaincopy

[_textField.rac_textSignalsubscribeNext:^(idx)?{

//?x:文本框的文字

NSLog(@"%@",x);

}];

第6種:處理當(dāng)界面有多次請求時傻昙,需要都獲取到數(shù)據(jù)時,才能展示界面

rac_liftSelector:withSignalsFromArray:Signals:當(dāng)傳入的Signals(信號數(shù)組)规丽,

每一個signal都至少sendNext過一次松捉,就會去觸發(fā)第一個selector參數(shù)的方法

[objc]view plaincopy

RACSignal*requestHot?=?[RACSignalcreateSignal:^RACDisposable*(id?subscriber)?{

NSLog(@"請求最熱商品");

[subscribersendNext:@"獲取最熱商品"];

returnnil;

}];

RACSignal*requestNew?=?[RACSignalcreateSignal:^RACDisposable*(id?subscriber)?{

NSLog(@"請求最新商品");

//????????[subscriber?sendNext:@"獲取最新商品"];

returnnil;

}];

//?Selector調(diào)用:當(dāng)所有信號都發(fā)送數(shù)據(jù)的時候調(diào)用

//?數(shù)組存放信號

//?Selector注意點:參數(shù)根據(jù)數(shù)組元素決定

//?Selector方法參數(shù)類型,就是信號傳遞出來數(shù)據(jù)

[selfrac_liftSelector:@selector(updateUI:data2:)withSignalsFromArray:@[requestHot,requestNew]];

}

//?只要兩個請求都請求完成的時候才會調(diào)用

-?(void)updateUI:(NSString*)data1data2:(NSString*)data2

{

NSLog(@"%@?%@",data1,data2);

}

2.ReactiveCocoa常見宏

第一種

RAC(TARGET, [KEYPATH, [NIL_VALUE]]):用于給某個對象的某個屬性綁定

[objc]view plaincopy

//?給某個對象的某個屬性綁定一個信號,只要產(chǎn)生信號,就會把信號的內(nèi)容給對象的屬性賦值

//?給label的text屬性綁定一個信號

RAC(_label,text)?=?_texfField.rac_textSignal;

第二種

RACObserve(self, name):監(jiān)聽某個對象的某個屬性,返回的是信號

[objc]view plaincopy

//?觀察某個對象某個屬性

[RACObserve(self,?name)subscribeNext:^(idx)?{

NSLog(@"%@",x);

}];

第三種

@weakify(Obj)和@strongify(Obj),一般兩個都是配套使用,解決循環(huán)引用問題

第四種

RACTuplePack:把數(shù)據(jù)包裝成RACTuple(元組類)

[objc]view plaincopy

//?RACTuplePack:快速把一些數(shù)據(jù)包裝成元組類

RACTuple*tuple?=?RACTuplePack(@"123",@1);

第五種

RACTupleUnpack:把RACTuple(元組類)解包成對應(yīng)的數(shù)據(jù)

[objc]view plaincopy

//?參數(shù):需要解析生成出來變量名

RACTupleUnpack(NSString*str,NSNumber*num)?=?tuple;

NSLog(@"%@?%@",str,num);

3.ReactiveCocoa常見操作方法

ReactiveCocoa操作原理

所有的信號(RACSignal)都可以進(jìn)行操作處理是越,因為所有操作方法都定義在RACStream.h中蔑歌,因此只要繼承RACStream就有了操作處理方法

ReactiveCocoa操作思想

運用的是Hook(鉤子)思想震叙,Hook是一種用于改變API(應(yīng)用程序編程接口:方法)執(zhí)行結(jié)果的技術(shù). Hook用處:截獲API調(diào)用的技術(shù)掀鹅。 Hook原理:在每次調(diào)用一個API返回結(jié)果之前,先執(zhí)行你自己的方法媒楼,改變結(jié)果的輸出

ReactiveCocoa核心方法bind

ReactiveCocoa操作的核心方法是bind(綁定),而且RAC中核心開發(fā)方式乐尊,也是綁定,之前的開發(fā)方式是賦值划址,而用RAC開發(fā)扔嵌,應(yīng)該把重心放在綁定,也就是可以在創(chuàng)建一個對象的時候夺颤,就綁定好以后想要做的事情痢缎,而不是等賦值之后在去做事情

核心方法bind的使用

[objc]view plaincopy

RACSignal*bindSignal?=?[_textField.rac_textSignalbind:^RACStreamBindBlock{

//?block調(diào)用時刻:只要一個信號被綁定就會調(diào)用.表示信號綁定完成

NSLog(@"源信號被綁定");

return^RACStream*(idvalue,BOOLBOOL*stop){

//?RACStreamBindBlock什么時候調(diào)用:每次源信號發(fā)出內(nèi)容,就會調(diào)用這個block

//?value:源信號發(fā)出的內(nèi)容

NSLog(@"源信號發(fā)出的內(nèi)容:%@",value);

//?RACStreamBindBlock作用:在這個block處理源信號的內(nèi)容

value?=?[NSStringstringWithFormat:@"xmg%@",value];

//?block返回值:信號(把處理完的值包裝成一個信號,返回出去)

//?創(chuàng)建一個信號,并且這個信號的傳遞的值是我們處理完的值,value

return[RACReturnSignalreturn:value];

};

}];

//?訂閱綁定信號,不在是源信號

[bindSignalsubscribeNext:^(idx)?{

NSLog(@"%@",x);

}];

//?執(zhí)行流程

/*

1.文字改變源信號

2.綁定源信號,[_textField.rac_textSignal?bind]

*?調(diào)用bind返回綁定好的信號,didSubscribe

3.訂閱綁定信號

*?創(chuàng)建訂閱者

*?調(diào)用綁定信號的didSubscribe

4.執(zhí)行綁定信號didSubscribe

5.執(zhí)行bind方法傳入的block

6.訂閱源信號

7.只要源信號一發(fā)出內(nèi)容,就會調(diào)用id?signal?=?bindingBlock(x,?&stop);

*?signal:把值處理完的信號

*/

ReactiveCocoa操作方法之映射(flattenMap,Map)

flattenMap:信號中信號,signalOfSignals

[objc]view plaincopy

[[_textField.rac_textSignalflattenMap:^RACStream*(idvalue)?{

//?value:源信號的內(nèi)容

value?=?[NSStringstringWithFormat:@"xmg%@",value];

//?返回值:信號,把處理完的值包裝成信號返回出去

return[RACReturnSignalreturn:value];

}]subscribeNext:^(idx)?{

//?訂閱[RACReturnSignal?return:value發(fā)送值

//?x:綁定信號的值

NSLog(@"%@",x);

}];

[objc]view plaincopy

map:?用于普通信號,信號發(fā)出普通值

[objc]view plaincopy

[[_textField.rac_textSignalmap:^id(idvalue)?{

//?value:源信號的內(nèi)容

//?返回值,就是處理源信號的內(nèi)容,直接返回

return[NSStringstringWithFormat:@"----xmg%@",value];

}]subscribeNext:^(idx)?{

NSLog(@"%@",x);

}];

FlatternMap和Map的區(qū)別

1.FlatternMap中的Block返回信號。

2.Map中的Block返回對象世澜。

3.開發(fā)中独旷,如果信號發(fā)出的值不是信號,映射一般使用Map

4.開發(fā)中寥裂,如果信號發(fā)出的值是信號嵌洼,映射一般使用FlatternMap。

ReactiveCocoa操作方法之組合

concat:按一定順序拼接信號封恰,當(dāng)多個信號發(fā)出的時候麻养,有順序的接收信號

[objc]view plaincopy

//?concat:連接信號,有順序的拼接,一定要等第一個信號完成的時候,第二個信號才會被激活

RACSubject*signalA?=?[RACSubjectsubject];

RACSubject*signalB?=?[RACSubjectsubject];

//?組合信號

RACSignal*signals?=?[signalAconcat:signalB];

//?訂閱組合信號

[signalssubscribeNext:^(idx)?{

NSLog(@"%@",x);

}];

//?發(fā)送數(shù)據(jù)

[signalAsendNext:@1];

[signalAsendCompleted];

[signalBsendNext:@2];

then:用于連接兩個信號,當(dāng)?shù)谝粋€信號完成诺舔,才會連接then返回的信號

[objc]view plaincopy

RACSubject*signalA?=?[RACSubjectsubject];

RACSubject*signalB?=?[RACSubjectsubject];

//?組合

RACSignal*signals?=?[signalAthen:^RACSignal*{

returnsignalB;

}];

[signalssubscribeNext:^(idx)?{

NSLog(@"%@",x);

}];

[signalAsendNext:@1];

[signalAsendCompleted];

[signalBsendNext:@2];

then跟concat區(qū)別:監(jiān)聽不到第一個信號的值,共同點都是必須第一個信號完成,第二個信號才會激活

merge: 把多個信號合并為一個信號回溺,任何一個信號有新值的時候就會調(diào)用

[objc]view plaincopy

//?merge:合并,任何一個信號只要發(fā)送值,就能訂閱

RACSubject*signalA?=?[RACSubjectsubject];

RACSubject*signalB?=?[RACSubjectsubject];

RACSignal*signals?=?[signalAmerge:signalB];

[signalssubscribeNext:^(idx)?{

NSLog(@"%@",x);

}];

[signalAsendNext:@1];

[signalBsendNext:@2];

[signalBsendNext:@3];

zipWith:把兩個信號壓縮成一個信號,只有當(dāng)兩個信號同時發(fā)出信號內(nèi)容時混萝,

并且把兩個信號的內(nèi)容合并成一個元組遗遵,才會觸發(fā)壓縮流的next事件

[objc]view plaincopy

RACSubject*signalA?=?[RACSubjectsubject];

RACSubject*signalB?=?[RACSubjectsubject];

RACSignal*signals?=?[signalAzipWith:signalB];

[signalssubscribeNext:^(idx)?{

NSLog(@"%@",x);

}];

//?zipWith:當(dāng)兩個信號都發(fā)出內(nèi)容的時候,才能被訂閱到

[signalAsendNext:@1];

[signalBsendNext:@2];

[signalBsendNext:@3];

[signalAsendNext:@4];

combineLatest:將多個信號合并起來,并且拿到各個信號的最新的值,必須每個合并的signal至少都

有過一次sendNext逸嘀,才會觸發(fā)合并的信號

[objc]view plaincopy

//?第一個參數(shù):就是存放需要合并信號

[[RACSignalcombineLatest:@[_textField1.rac_textSignal,_textField2.rac_textSignal]reduce:^id(NSString*str1,NSString*str2){

NSLog(@"%@?----?%@",str1,str2);

//?block:只要任意一個信號發(fā)出內(nèi)容,就會調(diào)用

//?block參數(shù)個數(shù):由信號決定

//?block參數(shù)類型:block的參數(shù)就是信號發(fā)出值

//?把兩個信號中的值聚合成哪個值

return@(str1.length&&?str2.length);

}]subscribeNext:^(idx)?{

_btn.enabled=?[xboolValue];

NSLog(@"%@",x);

}];

reduce聚合:用于信號發(fā)出的內(nèi)容是元組车要,把信號發(fā)出元組的值聚合成一個值

[objc]view plaincopy

RACSignal*signalA?=?[RACSignalcreateSignal:^RACDisposable*(id?subscriber)?{

[subscribersendNext:@1];

returnnil;

}];

RACSignal*signalB?=?[RACSignalcreateSignal:^RACDisposable*(id?subscriber)?{

[subscribersendNext:@2];

returnnil;

}];

//?聚合

//?常見的用法,(先組合在聚合)崭倘。combineLatest:(id)signals?reduce:(id?(^)())reduceBlock

//?reduce中的block簡介:

//?reduceblcok中的參數(shù)翼岁,有多少信號組合,reduceblcok就有多少參數(shù)司光,每個參數(shù)就是之前信號發(fā)出的內(nèi)容

//?reduceblcok的返回值:聚合信號之后的內(nèi)容琅坡。

CSignal*reduceSignal?=?[RACSignalcombineLatest:@[signalA,signalB]reduce:^id(NSNumber*num1,NSNumber*num2){

return[NSStringstringWithFormat:@"%@?%@",num1,num2];

];

[reduceSignalsubscribeNext:^(idx)?{

NSLog(@"%@",x);

}];

ReactiveCocoa操作方法之過濾

filter:過濾信號,使用它可以獲取滿足條件的信號

ignore:忽略完某些值的信號

distinctUntilChanged:當(dāng)上一次的值和當(dāng)前的值有明顯的變化就會發(fā)出信號残家,否則會被忽略掉

take:從開始一共取N次的信號

takeLast:取最后N次的信號,前提條件榆俺,訂閱者必須調(diào)用完成,因為只有完成,就知道總共有多少信號

takeUntil:(RACSignal *):獲取信號直到執(zhí)行完這個信號

skip:(NSUInteger):跳過幾個信號,不接受

switchToLatest:用于signalOfSignals(信號的信號)茴晋,有時候信號也會發(fā)出信號陪捷,會在signalOfSignals中,獲取signalOfSignals發(fā)送的最新信號

ReactiveCocoa操作方法之秩序

doNext: 執(zhí)行Next之前诺擅,會先執(zhí)行這個Block

doCompleted: 執(zhí)行sendCompleted之前市袖,會先執(zhí)行這個Block

ReactiveCocoa操作方法之線程

deliverOn: 內(nèi)容傳遞切換到制定線程中,副作用在原來線程中,把在創(chuàng)建信號時block中的代碼稱之為副作用

subscribeOn: 內(nèi)容傳遞和副作用都會切換到制定線程中

ReactiveCocoa操作方法之時間

timeout:超時烁涌,可以讓一個信號在一定的時間后苍碟,自動報錯

interval 定時:每隔一段時間發(fā)出信號

delay: 延遲發(fā)送next

ReactiveCocoa操作方法之重復(fù)

retry重試 :只要失敗,就會重新執(zhí)行創(chuàng)建信號中的block,直到成功

replay重放:當(dāng)一個信號被多次訂閱,反復(fù)播放內(nèi)容

throttle節(jié)流:當(dāng)某個信號發(fā)送比較頻繁時撮执,可以使用節(jié)流微峰,在某一段時間不發(fā)送信號內(nèi)容,過了一段時間獲取信號的最新內(nèi)容發(fā)出

4.學(xué)習(xí)MVVM架構(gòu)思想

(1)程序為什么要架構(gòu)二打?

便于程序員開發(fā)和維護(hù)代碼

(2)常見的架構(gòu)思想有哪些县忌?

MVC ---- M:模型 V:視圖 C:控制器)

MVVM ----M:模型 V:視圖+控制器 VM:視圖模型

MVCS ---- M:模型 V:視圖 C:控制器 S:服務(wù)類

VIPER ---- V:視圖 I:交互器 P:展示器 E:實體 R:路由

(3)MVVM思想

模型(M):保存視圖數(shù)據(jù)

視圖+控制器(V):展示內(nèi)容 + 如何展示

視圖模型(VM):處理展示的業(yè)務(wù)邏輯,包括按鈕的點擊继效,數(shù)據(jù)的請求和解析

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末症杏,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子瑞信,更是在濱河造成了極大的恐慌厉颤,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,430評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凡简,死亡現(xiàn)場離奇詭異逼友,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)秤涩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評論 3 398
  • 文/潘曉璐 我一進(jìn)店門帜乞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人筐眷,你說我怎么就攤上這事黎烈。” “怎么了匀谣?”我有些...
    開封第一講書人閱讀 167,834評論 0 360
  • 文/不壞的土叔 我叫張陵照棋,是天一觀的道長。 經(jīng)常有香客問我武翎,道長烈炭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,543評論 1 296
  • 正文 為了忘掉前任宝恶,我火速辦了婚禮符隙,結(jié)果婚禮上趴捅,老公的妹妹穿的比我還像新娘。我一直安慰自己膏执,他們只是感情好驻售,可當(dāng)我...
    茶點故事閱讀 68,547評論 6 397
  • 文/花漫 我一把揭開白布露久。 她就那樣靜靜地躺著更米,像睡著了一般。 火紅的嫁衣襯著肌膚如雪毫痕。 梳的紋絲不亂的頭發(fā)上征峦,一...
    開封第一講書人閱讀 52,196評論 1 308
  • 那天,我揣著相機(jī)與錄音消请,去河邊找鬼栏笆。 笑死,一個胖子當(dāng)著我的面吹牛臊泰,可吹牛的內(nèi)容都是我干的蛉加。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼缸逃,長吁一口氣:“原來是場噩夢啊……” “哼针饥!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起需频,我...
    開封第一講書人閱讀 39,671評論 0 276
  • 序言:老撾萬榮一對情侶失蹤丁眼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后昭殉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體苞七,經(jīng)...
    沈念sama閱讀 46,221評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,303評論 3 340
  • 正文 我和宋清朗相戀三年挪丢,在試婚紗的時候發(fā)現(xiàn)自己被綠了蹂风。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,444評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡乾蓬,死狀恐怖惠啄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情巢块,我是刑警寧澤礁阁,帶...
    沈念sama閱讀 36,134評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站族奢,受9級特大地震影響姥闭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜越走,卻給世界環(huán)境...
    茶點故事閱讀 41,810評論 3 333
  • 文/蒙蒙 一棚品、第九天 我趴在偏房一處隱蔽的房頂上張望靠欢。 院中可真熱鬧,春花似錦铜跑、人聲如沸门怪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽掷空。三九已至,卻和暖如春囤锉,著一層夾襖步出監(jiān)牢的瞬間坦弟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評論 1 272
  • 我被黑心中介騙來泰國打工官地, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留酿傍,地道東北人。 一個月前我還...
    沈念sama閱讀 48,837評論 3 376
  • 正文 我出身青樓驱入,卻偏偏與公主長得像赤炒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子亏较,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,455評論 2 359

推薦閱讀更多精彩內(nèi)容