RAC-響應(yīng)式編程


什么是RAC:

git 重量型開源項目,主要是針對各種事件的處理 拌倍。

什么是響應(yīng)式編程:

一個簡單的理解:如果a + b =c 修改 a 在 修改 b c會變嗎暇番?結(jié)果是不會變的 于个,如果c 變是需要再次調(diào)用 a + b = c 這個計算镐作,響應(yīng)式編程:就是修改a 或者 b 的時候 c就會 立即變換锈津。所以說:響應(yīng)式編程就是 在事件發(fā)生變換的時候立即做出相應(yīng).


IOS 開發(fā)中有哪些事件發(fā)生:

tagrget

delegate

kvo

通知

時鐘(NSTime)

網(wǎng)絡(luò)異步回調(diào)


RAC家族:4大家族


備注:(如果只使用 請使用 3.0.0以下并且 指點家族 )

pod search ReactiveObjC


RACSignal:

具體使用: 簡稱《信號3部曲》

/*

信號:

1:創(chuàng)建信號 :(冷信號)

2:訂閱信號:(熱信號)

3:發(fā)送信號:

*/

//? ? 創(chuàng)建信號(冷信號)

RACSignal *signal =? [RACSignal createSignal:^RACDisposable *(id subscriber) {

//? ? ? ? 發(fā)送信號

[subscriber sendNext:@"this is signal"];

return nil;

}];

//? ? 訂閱信號? (subscribe) 訂閱(熱信號)

[signal subscribeNext:^(id x) {

//? ? ? x :信號內(nèi)容

NSLog(@"x is value :%@ ",x);

}];


構(gòu)造方法分析

+ (RACSignal *)createSignal:(RACDisposable * (^)(id subscriber))didSubscribe {

return [RACDynamicSignal createSignal:didSubscribe];

}

RACDynamicSignal:動態(tài)信號

看看這個方法:

[RACDynamicSignal createSignal:didSubscribe]

+ (RACSignal *)createSignal:(RACDisposable * (^)(id subscriber))didSubscribe {

RACDynamicSignal *signal = [[self alloc] init];

signal->_didSubscribe = [didSubscribe copy];

return [signal setNameWithFormat:@"+createSignal:"];

}

結(jié)論:創(chuàng)建信號的時候干了2件事情

1:創(chuàng)建了RACDynamicSignal

2:保存一個block didSubscribe


創(chuàng)建信號的內(nèi)部處理:

//? ? 創(chuàng)建冷信號

RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id? _Nonnull subscriber) {

NSLog(@"創(chuàng)建信號");

[subscriber sendNext:@"發(fā)送信號已經(jīng)收到"];

NSLog(@"發(fā)送信號");

return nil;

}];

//? ? 訂閱信號 (熱信號)

[signal subscribeNext:^(id? _Nullable x) {

//? ? ? ? x:信號內(nèi)容

NSLog(@"this is %@",x);

NSLog(@"我訂閱了信號");

}];

1:測試: 將訂閱信號注釋掉 查看日志 結(jié)果是什么都沒有 so 假設(shè)結(jié)論:創(chuàng)建信號必須先訂閱

2:測試:將發(fā)送信號代碼去掉:結(jié)果 :打印出創(chuàng)建信號log so 假設(shè)結(jié)論:我要訂閱信號必須先發(fā)送


訂閱信號的內(nèi)部處理

//? ? 訂閱信號 (熱信號)

[signal subscribeNext:^(id? _Nullable x) {

//? ? ? ? x:信號內(nèi)容

NSLog(@"this is %@",x);

NSLog(@"我訂閱了信號");

}];

進(jìn)入 subscribeNext :

- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock {

NSCParameterAssert(nextBlock != NULL);

RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];

return [self subscribe:o];

}

*記錄下nextBlock

在進(jìn)入:subscriberWithNext: 發(fā)現(xiàn)創(chuàng)建了RACSubscriber 點擊進(jìn)入 subscribe:選擇 RACDynamicSignal 的方法呀酸,發(fā)現(xiàn) 在subscribe方法中執(zhí)行了,self.didSubscribe(subscriber) 這里解釋了:創(chuàng)建信號必須先訂閱(不訂閱 block 就不執(zhí)行)

如果 我要訂閱信號必須先發(fā)送

- (void)sendNext:(id)value {

@synchronized (self) {

void (^nextBlock)(id) = [self.next copy];

if (nextBlock == nil) return;

nextBlock(value);

}

}

執(zhí)行nextBlock


具體的流程如下:


RAC 的簡單使用



KVO的簡單使用

kvo 的使用實現(xiàn)對_p對象的 name 屬性監(jiān)聽

//? ? kvo

_p = [[Person alloc]init];

//? ? 對P監(jiān)聽

[RACObserve(self.p, name)subscribeNext:^(id? _Nullable x) {

NSLog(@"x is value? %@",x);

}];

點擊屏幕修改p的name值

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

self.p.name = [NSString stringWithFormat:@"mrlee %05d",arc4random_uniform(200)];

}


target使用

一句話搞定 創(chuàng)建 訂閱 發(fā)送 三部曲

[[self.button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {

NSLog(@"x is value %@",x);

}];

我們點擊按鈕顯示x的值為:

x is value button

拿個這個是不是想干啥 就干啥~


輸入框點擊監(jiān)聽

[[self.textField rac_textSignal]subscribeNext:^(NSString * _Nullable x) {

NSLog(@"x is value %@",x);

}


通知

[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil]subscribeNext:^(NSNotification * _Nullable x) {

NSLog(@"ios is value %@",x);

}];


RAC中的坑

循環(huán)引用

1.制作循環(huán)引用案例

首先 做a push b 頁面 在b頁面添加如下代碼

-(void)dealloc{

NSLog(@"bay bay !");

}

在從b pop 回 a 打印出bay bay ! 說明VC 釋放

修改下

- (void)viewDidLoad {

[super viewDidLoad];

[self demo2];

}

-(void)demo2{

//? ? 信號的生成

[[self.button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {

NSLog(@"x is value %@",x);

self.textField.text =@"你好~";

}];

}

點擊按鈕 在pop 回 a 沒有走bay bay ! 說明循環(huán)引用

修改下

//? ? 信號的生成

__weak typeof (self) weakSelf = self;

[[self.button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {

NSLog(@"x is value %@",x);

weakSelf.textField.text =@"你好~";

}];

打印bay bay

RAC 提供了相關(guān)解決方案 @weakify(self);? @strongify(self);

//? ? 信號的生成

@weakify(self);

[[self.button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {

@strongify(self);

NSLog(@"x is value %@",x);

self.textField.text =@"你好~";

}];


是如何造成循環(huán)引用的


self.btn 對 self.view.subview 進(jìn)行強(qiáng)引用 self.textField 是self.btn 對其強(qiáng)引用 因為 他是在self.btn的Block中 self.textField 又被self.view.subview 進(jìn)行強(qiáng)引用 so 循環(huán)引用

這個說明:只要在rac中用了self 就會造成循環(huán)引用琼梆,解決辦法 @weakify 和 @strongify



Command命令

//? ? 創(chuàng)建命令

RACCommand *command = [[RACCommand alloc]initWithSignalBlock:^RACSignal * _Nonnull(id? _Nullable input) {

return nil;

}];

//? ? 執(zhí)行命令

[command execute:@"xx"];

運行這段代碼 會發(fā)現(xiàn) app carsh 掉了 原因是因為 return nil; 應(yīng)該返回一個信號

修改后

//? ? 創(chuàng)建命令

RACCommand *command = [[RACCommand alloc]initWithSignalBlock:^RACSignal * _Nonnull(id? _Nullable input) {

return [RACSignal createSignal:^RACDisposable * _Nullable(id? _Nonnull subscriber) {

return nil;

}];

}];

//? ? 執(zhí)行命令

[command execute:@"xx"];

input:執(zhí)行命令的內(nèi)容 (輸入的指令)這樣就不會崩潰了但是一個流程還沒有走完 還差個接收 一個完整的流程如下

//? ? 創(chuàng)建命令

RACCommand *command = [[RACCommand alloc]initWithSignalBlock:^RACSignal * _Nonnull(id? _Nullable input) {

//? ? ? ? input 執(zhí)行命令里的內(nèi)容

return [RACSignal createSignal:^RACDisposable * _Nullable(id? _Nonnull subscriber) {

[subscriber sendNext:@"我是從命令里面發(fā)送的消息"];

return nil;

}];

}];

//? ? 執(zhí)行命令

[[command execute:@"xx"] subscribeNext:^(id? _Nullable x) {

NSLog(@"x is value %@",x);

}];


MVVM

具體是什么是mvvm 我想不用說也有很多的資料講解 性誉。這里直接就不多說了,只說如下幾點

1:MVVM :就是MVC的瘦身劑

2:MVVM 方便功能測試

下面做個簡單的登錄頁面 :需求 如果沒有輸入 userName 或者pwd 登錄按鈕是無法點擊

具體實現(xiàn)如下:

//? ? 綁定

//? ? 多個信號綁定成一個信號

[[RACSignal combineLatest:@[self.userName.rac_textSignal,self.passWord.rac_textSignal] reduce:^id _Nullable(NSString *userName,NSString *pwd){

return @(userName.length && pwd.length);

}]subscribeNext:^(id? _Nullable x) {

NSLog(@"x is value %@",x);

}];

1使用:combineLatest reduce 進(jìn)行多個信號的綁定

// RAC(self.loginBtn,enabled) 監(jiān)聽 UI 的狀態(tài)? 整合后

RAC(self.loginBtn,enabled) =? [RACSignal combineLatest:@[self.userName.rac_textSignal,self.passWord.rac_textSignal] reduce:^id _Nullable(NSString *userName,NSString *pwd){

return @(userName.length && pwd.length);

}];

OK 搞定 么又看出就這一句代碼搞定 判斷 username 和 pwd都必須都有值 才可以點點擊按鈕

RAC(target,...) 用于監(jiān)聽 一個對象的相關(guān)屬性 返回的為 RACSignal

combineLatest 綁定多個有共性的信號

demo地址如果對您有用請點個star

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末茎杂,一起剝皮案震驚了整個濱河市错览,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌煌往,老刑警劉巖倾哺,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異刽脖,居然都是意外死亡羞海,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門曲管,熙熙樓的掌柜王于貴愁眉苦臉地迎上來却邓,“玉大人,你說我怎么就攤上這事院水±搬悖” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵檬某,是天一觀的道長昧穿。 經(jīng)常有香客問我,道長橙喘,這世上最難降的妖魔是什么时鸵? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上饰潜,老公的妹妹穿的比我還像新娘初坠。我一直安慰自己,他們只是感情好彭雾,可當(dāng)我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布碟刺。 她就那樣靜靜地躺著,像睡著了一般薯酝。 火紅的嫁衣襯著肌膚如雪半沽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天吴菠,我揣著相機(jī)與錄音者填,去河邊找鬼。 笑死做葵,一個胖子當(dāng)著我的面吹牛占哟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播酿矢,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼榨乎,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了瘫筐?” 一聲冷哼從身側(cè)響起蜜暑,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎策肝,沒想到半個月后肛捍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡驳糯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了氢橙。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酝枢。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖悍手,靈堂內(nèi)的尸體忽然破棺而出帘睦,到底是詐尸還是另有隱情,我是刑警寧澤坦康,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布竣付,位于F島的核電站,受9級特大地震影響滞欠,放射性物質(zhì)發(fā)生泄漏古胆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望逸绎。 院中可真熱鬧惹恃,春花似錦、人聲如沸棺牧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽颊乘。三九已至参淹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間乏悄,已是汗流浹背浙值。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留纲爸,地道東北人亥鸠。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像识啦,于是被迫代替她去往敵國和親负蚊。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,724評論 2 354

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

  • 前言 之前對RAC有了一個基本的認(rèn)識颓哮,了解了它的作用家妆,以及RAC的運行機(jī)制,我們知道只要是信號(RACSignal...
    大大盆子閱讀 4,498評論 0 11
  • RAC使用測試Demo下載:github.com/FuWees/WPRACTestDemo 1.ReactiveC...
    FuWees閱讀 6,368評論 3 10
  • 1.ReactiveCocoa常見操作方法介紹冕茅。 1.1 ReactiveCocoa操作須知 所有的信號(RACS...
    萌芽的冬天閱讀 1,023評論 0 5
  • 前言由于時間的問題伤极,暫且只更新這么多了,后續(xù)還會持續(xù)更新本文《最快讓你上手ReactiveCocoa之進(jìn)階篇》姨伤,目...
    Karos_凱閱讀 1,739評論 0 6
  • 燥熱難耐的午后哨坪,我坐在電扇風(fēng)口下,揮汗如雨乍楚。 沒有空調(diào)当编。 下午2點30分,這是我打的第三通電話徒溪,那是種清澈通透的音...
    肖夢芹閱讀 336評論 1 3