ReactiveCocoa的核心:
信號闽巩,沒錯就是信號糯俗,發(fā)了信號要干嘛干嘛饶唤,講白了就是一個事件流;
那么我們來把這件事做一個形象的比喻:
可以把信號想象成水龍頭光绕,只不過里面不是水女嘲,
而是玻璃球(value),直徑跟水管的內(nèi)徑一樣诞帐,
這樣就能保證玻璃球是依次排列欣尼,不會出現(xiàn)并排的情況
(數(shù)據(jù)都是線性處理的,不會出現(xiàn)并發(fā)情況)停蕉。
水龍頭的開關(guān)默認(rèn)是關(guān)的愕鼓,除非有了接收方(subscriber),才會打開谷徙。
這樣只要有新的玻璃球進(jìn)來拒啰,就會自動傳送給接收方。
可以在水龍頭上加一個過濾嘴(filter)完慧,不符合的不讓通過谋旦,
也可以加一個改動裝置,把球改變成符合自己的需求(map)屈尼。
也可以把多個水龍頭合并成一個新的水龍頭(combineLatest:reduce:)册着,
這樣只要其中的一個水龍頭有玻璃球出來,
這個新合并的水龍頭就會得到這個球脾歧。
需要說明的是因?yàn)镽AC使用大量的block甲捏,請避免循環(huán)引用
例如:
[RACObserve(self,username) subscribeNext:^(NSString *newName){
NSLog(@"Name changed to %@",newName);
}];
RACObserve使用kvo來監(jiān)聽username的變化,只要有變化就會執(zhí)行block鞭执。
但不是所有的property都可以被RACObserve司顿,該property必須支持KVO芒粹,比如NSURLCache的currentDiskUsage就不能被RACObserve。
Signal和Subscriber
Signal獲取到數(shù)據(jù)后大溜,會調(diào)用Subscriber的sendNext,
sendComplete, sendError方法來傳送數(shù)據(jù)給Subscriber,Subscriber自然也有方法來獲取傳過來的數(shù)據(jù)化漆,如:
[signal subscribeNext:error:completed]。這樣只要沒有sendComplete和sendError钦奋,
新的值就會通過sendNext源源不斷地傳送過來.
ReactiveCocoa signal(RACSignal)
發(fā)送事件流給它的subscriber座云。
目前共有三種類型的事件:
next、__error__付材、completed朦拖。
一個signal在因error終止或者完成前,可以發(fā)送任意數(shù)量的next事件.
RACSignal有很多方法可以來訂閱不同的事件類型厌衔。
每個方法都需要至少一個block璧帝,當(dāng)事件發(fā)生時就會執(zhí)行block中的邏輯。
ReactiveCocoa 框架使用 category 來為很多基本UIKit控件添加signal葵诈。
這樣就能給控件添加訂閱了裸弦,比如 text field 的 rac_textSignalRACSignal的每個操作都會返回一個RACsignal祟同,
這在術(shù)語上叫做連貫接口(fluent interface)作喘。這個功
能可以讓你直接構(gòu)建管道,而不用每一步都使用本地變量晕城。
片段解析:
-
只要 text 有變化泞坦, 將 text 發(fā)送給 Subscriber
[self.usernameTextField.rac_textSignal subscribeNext:^(id x){ NSLog(@"%@", x);
}];
篩選長度 >3, 滿足則發(fā)送給 Subscriber
[[self.usernameTextField.rac_textSignal
filter:^BOOL(NSString *text){
return text.length > 3;
}]
subscribeNext:^(id x){
NSLog(@"%@", x);
}];
上面代碼如果按步驟來:
RACSignal *usernameSourceSignal =
self.usernameTextField.rac_textSignal;
RACSignal *filteredUsername = [usernameSourceSignal
filter:^BOOL(id value){
NSString*text = value;
return text.length > 3;
}];
[filteredUsername subscribeNext:^(id x){
NSLog(@"%@", x);
}];
-
在管道中添加map:
這里的 map 操作之后的步驟收到的都是NSNumber實(shí)例。
可以使用map操作來把接收的數(shù)據(jù)轉(zhuǎn)換成想要的類型砖顷,只要它是對象贰锁。**[[[self.usernameTextField.rac_textSignal map:^id(NSString*text){ return @(text.length); }] filter:^BOOL(NSNumber*length){ return[length integerValue] > 3; }] subscribeNext:^(id x){ NSLog(@"%@", x); }];
新加的map操作通過block改變了事件的數(shù)據(jù)。map從上一個next事件接收數(shù)據(jù)滤蝠,通過執(zhí)行block把返回值傳給下一個next事件豌熄。在上面的代碼中,map以NSString為輸入物咳,取字符串的長度锣险,返回一個NSNumber。
結(jié)尾:
簡明語法入門览闰,圖文并茂:
http://www.teehanlax.com/blog/reactivecocoa/
參考:
http://benbeng.leanote.com/post/ReactiveCocoaTutorial-part1