我廠廣招各路大神加入:job.koudaitong.com
能夠發簡歷到 tianchi@qima-inc.com O(∩_∩)O~html
這個結結實實是一個巨坑,英語水平、技術水平有限,只是嘗試着翻譯一下,雖然ReactiveCocoa已經很流行,不過再segmentfault上還沒看到他的蹤跡。react
本文包含了ReactiveCocoa框架內的不一樣組成部分的一個高層次的描述,並試圖解釋它們如何協做以及劃分責任。這是一個學信新的模塊以及尋找更具體的文件的一個開始。ios
由RACStream抽象類來表示的Steam是任意對象的值的一個序列(any series of object values
)。git
值能夠當即使用也能夠在以後使用,可是必須按照順序進行檢索。不能在沒有獲取或者等待(without evaluating or waiting for the first value
)第一個值的狀況下獲取第二個值。github
Steams是單子(monads),除其餘事項外,這使得複雜的操做必須創建在一些基本的原函數(primitives)上(特別是-bind:
)。RACSteam也實現了Haskell中Monoid與MonadZip類型的等效(the equivalent of the Monoid and MonadZip typeclasses from Haskell
)。segmentfault
RACStream自身並非十分有用。大多數stream被看成信號和序列來使用(treated as signals or sequences instead
)。api
Signal有RACSignal類描述。它是一個push-driven的流。數組
信號通常表示將要傳遞的數據,隨着工做(方法)的執行或者數據的接受,數據經過信號獲得傳遞到訂閱者(subscribers
)處。用戶必須訂閱(subscribe
)一個信號來訪問它的值。網絡
在三種不一樣類型的事件下信號會被髮送給它的訂閱者:
(Signals send three different types of events to their subscribers:
)??
信號爲它的訂閱者發送三種不一樣類型的事件:app
next
)事件提供了新的值。RACSteam方法只會在這種類型的事件時執行。不想Cocoa中的collections,在信號中使用nil也是有效的。error evenet
)表示在信號結束前發生了一個錯誤。這個事件可能包含了一個NSError對象,指示什麼地方除了錯誤。錯誤必須獲得特殊的處理(handled specially
),由於它們不包含在steam的值中。complete
)事件表示信號成功的結束了,而且沒有更多的值被添加到steam中。完成後也必須進行特殊處理,緣由相同。一個信號的生命週期包括任何數量的next事件,以及一個error或者completed事件(二者不須要都有)。
訂閱者(subscriber)是正在等待或者可以等待來自信號的事件的任何對象。在RAC中,訂閱者被表示爲一個符合RACSubscriber協議的任何對象。
訂閱能夠經過調用-subscribeNext:error:completed:
或者相應的適宜的方法來建立。從技術上講,大部分RACStream和RACSignal方法可以很好的建立一個訂閱,可是,這些中間訂閱(intermediate subscriptions
)一般是一個實現細節(implementation detail
)。
訂閱保留(retain
)他們的信號,並在信號完成或者出錯時被處理。訂閱也能夠被手動地處理。
subject是一個能夠手動控制的信號。它由RACSubject類進行描述。
subject能夠看做是信號的一個「可變」變體(variant
),就像NSMutableArray
之於NSArray
。它對於橋接(bridging
)非RAC代碼到信號中去(into the world of signals
)很是有用。
舉例來講,block能夠簡單的發送一個事件(event)給共享的subject來替代在block的回調中處理應用程序邏輯。以後subject能夠返回一個RACSignal,隱藏回調的實現細節。
一些subject提供了額外的方法(behaviors
)。尤爲像RACReplaySubject可以被用來爲以後的訂閱者緩衝事件(buffer events
),好比,一個網絡請求在其餘準備好處理請求結果以前完成。(when a network request finishes before anything is ready to handle the result
)
command建立並訂閱一個信號以響應一些動做(action
)。這使得它很容易處理UI與應用之間的side-effecting work。
一般觸發command的動做是由UI驅動的,好比按鈕的點擊。命令也能夠根據信號被自動禁用,而且這種禁用狀態能過經過禁用任何與command相關的控件來表如今UI上。
在OS X上,RAC爲NSButton
增長了一個rac_command
屬性來自動設置上述行爲(behaviors
)。
connection是一個在任意數量訂閱者之間共享的一個訂閱(subscription)。它由RACMulticastConnection類表示。
信號在默認狀況下是「冷(code
)」的,意思是,每當有一個新的訂閱被添加了,信號就開始工做。這意味着每一個訂閱者的數據(data
)會被從新計算。這種行爲在通常狀況下是可取的,可是若是信號具備side effects或者所要作的工做代價是昂貴的(好比發送一個網絡請求)時,這就會有一些問題。
connection時經過RACSignal的-publish
或者-muticast:
方法建立的,並確保不管connection被訂閱了多少次,只有一個相關的訂閱被建立了。一旦鏈接了,鏈接的信號就被認爲是「熱(hot
)」的,而且那個相關訂閱會被保持活躍(remain active
)直到全部connection上的訂閱都被處理。
序列是個pull-driven的流,它由RACSequence類描述。
序列是一種集合,與NSArray
相似。可是與數組不一樣的是,sequence中的值在默認狀況下是延遲計算(evaluated lazily
)的,若是隻有一部分的sequence被使用,這會提升必定的性能。與Cocoa中的集合同樣,序列中不容許包含nil
。
序列與Clojure中的序列(特別是lazy-seq)以及Haskell中的List類型類似。
RAC給大多數Cocoa的集合類添加了-rac_sequence
方法,容許它們使用做爲RACSequences。
RACDisposables用於取消訂閱與資源清理(cancellation and resource cleanup
)。
Disposables最經常使用來退訂(unsubscribe
)一個信號。當一個訂閱被處理以後,相應的訂閱者將不會從信號中接受任何事件。另外,任何與訂閱相關的的工做(後臺進程、網絡請求等等)會被取消,結果也再也不須要。
Scheduler是信號執行工做以及返回它們的結果的一個串行執行隊列。它由RACScheduler類描述。
Scheduler相似於GCD的隊列(queue
),可是scheduler支持取消操做,而且始終串行執行。惟一的例外是+immediateScheduler
,schedulers不提供同步執行。這有助於避免死鎖,並促使(encourages
)用信號操做來替代block。
RACScheduler有時候也像NSOperationQueue
,可是schedulers不容許任務從新排序與相互依賴。
爲了方便表示流(steam
)中的值,RAC提供了一些雜類(miscellaneous classes):
singleton
)的「空」值。它被用來表示那些在留中不存在的更有意義的數據。signal event
)表示爲信號值(signal value
)。它主要經過RACSignal的-materialize
來使用。由於基於RAC的代碼每每設計到異步的工做以及隊列跳轉(queue-hopping
)。ReactiveCocoa框架支持支持捕獲異步回溯,使得調試更加容易。
在OS X中,回溯會自動從任何代碼捕捉,包括系統的庫。
在iOS中,只有隊列在RAC內跳轉你的項目纔會捕捉到(可是信息任然是有效的)。
是在是有點坑,有些東西不是很清楚特別是用英語,不知道怎麼翻譯成中文。因此用括號標記出來,先作一個記錄,在瞭解以後進行改進。
這只是我的的一個記錄,翻譯的很差不要噴我。附上一些學習RAC的網址:
http://blog.leezhong.com/ios/2013/06/19/frp-reactivecocoa.html
http://www.cnblogs.com/yangecnu/archive/2012/11/03/Introducting_ReactiveExtensions.html
http://www.cocoachina.com/applenews/devnews/2014/0115/7702.html
百度