譯者:@沒故事的卓同學
將翻譯幾篇reactivecocoa的文件,這是第一篇。
reactivecocoa (rac) 是乙個cocoa框架,受functional reactive programming啟發。它提供api合成變換(composing and transforming)隨著時間改變的資料流。
相容性
關於 rac 4的文件是在swift 2.1.x下使用。對於swift 1.2的支援請看 rac 3.
介紹
因為這些不同的機制能夠用一種相同的方式處理,可以很容易的宣告成鏈(chain)並且把它們聯合在一起,用更少的**和狀態連線它們。
更多關於rac裡的概念可以檢視framework overview.
假設你有乙個text field,每當使用者輸入文字時,你都會發起乙個網路請求根據輸入的關鍵字查詢。
實時觀察文字變化
實現這個目的的第一步,使用rac中uitextfield的乙個擴充套件方法:
1
2
3
let searchstrings = textfield.rac_textsignal()
.tosignalproducer()
.map
這樣產生了乙個signal producer來傳送輸入的字串。( text as! string這種型別對映在當前是必需的,為了從oc橋接當前的擴充套件方法)
傳送網路請求
獲得了每次輸入的字串,我們想要傳送乙個網路請求。rac也為我們提供了nsurlsession的乙個擴充套件方法來實現:
1
2
3
4
5
6
7
8
let searchresults = searchstrings
.flatmap(.latest)
.map
.observeon(uischeduler())
這段**將字串的producer轉換成了一組包含了搜尋結果的producer,並且會在主線程中處理(由於uischeduler的作用).。
另外這裡的flatmap(.latest)確保只有最後的一次搜尋會被執行。
如果當乙個請求還在處理中,此時使用者輸入新的字元,在發起新的請求之前會取消之前的請求。想想這些如果自己實現的需要寫多少**!
接收結果
這樣實際上還沒有執行,因為producers必須started後才執行(對於返回結果沒有被使用時做的優化)。這個很簡單:
1
2
3
searchresults.startwithnext
我們獲取值用於next中的event:包含了請求結果,並且把他們log到了控制台。這裡也可以寫其他ui控制的**,比如reload乙個table view。
失敗處理
到目前為止,這個例子中,任何的網路錯誤都會產生乙個failed event,這會導致整個事件流終止。不幸的是,這意味著之後請求不會被發起。
為了避免這樣的情況,我們需要決定當失敗發生時怎樣處理。最快速的解決方案就是記錄它們,然後忽略它們:
1
2
3
4
5
6
7
8
9
.flatmap(.latest)
}
通過將失敗替換為空事件流,可以有效的忽略它們。
然而,在放棄前最好重試幾次。在一次,使用retry可以方便的達到這個目的。
改進後的searchresults producer會像這樣:
1
2
3
4
5
6
7
8
9
10
11
12
13
let searchresults = searchstrings
.flatmap(.latest) }
.map
.observeon(uischeduler())
降低請求頻率
現在,我們假設你只希望在使用者輸入暫停時才發起請求以減少網路請求。
rac通過throttle操作符可以用於實現這個需求:
1
2
3
4
let searchstrings = textfield.rac_textsignal()
.tosignalproducer()
.map
.throttle(0.5, onscheduler: queuescheduler.mainqueuescheduler)
這樣當間隔小於0.5秒時值不會被傳送出去,意味著使用者必須停止編輯0.5秒後我們才會使用輸入的字串去搜尋。
如果用自己實現這個功能,真是要寫不少**,而且還會影響**的可讀性。但是在rac中,只需要乙個操作符就可以方便將時間控制加入事件流。
objective-c 和 swift
雖然rac是作為乙個oc的框架開始的,但是從版本3.0開始,所有的主要特性開發都是基於swift api。
rac的objective-c api和swift api是完全分開的,但是有乙個bridge可以將他們互相轉換。這主要是為了相容使用rac的一些老專案,或者用於一些還沒有被加入swfit api的一些cocoa擴充套件。
objective-c api將繼續存在,在可預計的未來將提供支援,但是不會有新的改進。關於使用這些api的資訊可以參考:legacy documentation。
我們強烈建議所有的新專案採用swift api。
reactivecocoa和rx的關係
reactivecocoa 受了 microsoft』s reactive extensions (rx)庫的不少影響。有很多對於rx的實現,包括rxswift,但是reactivecocoa無意於成為rx的乙個實現子集。
rac和 rx的區別,主要有以下一些:
命名
在大部分rx的版本中,流被稱為observables,對應於.net中的enumerable型別。
另外, rx.net大部分的操作符參考了linq,而linq是用於操作傳統關係型資料庫的,比如 select和 where。
rac則最關注於匹配swift的命名規範, 使用 map和 filter來替換select和where。其他的一些命名**於haskell或elm(使用「signal」的始祖)。
signals and signal producers (「hot」 and 「cold」 observables)
rx中的「hot」, 「cold」, and 「warm」 observables (對應rac中的事件流)很容易讓人困惑。
對於這個部分和typed errors的區別,因為在我翻譯的ios響應式程式設計:reactivecocoa vs rxswift 選誰好中有更詳細的對比說明,這裡就不翻譯了。
typed errors
處理錯誤時方式
ui程式設計
很多人不知道rx怎麼用。即使用rx進行ui的程式設計很常見,它有幾個特性用於一些特別的場景。
rac從reactiveui借鑑了很多,包括actions的基礎操作。
不像reactiveui不能直接將rx改變的對於ui程式設計更友好,為了這個目的則進行了很多次的改動—即使這意味著和rx的區別越來越大.
RabbitMQ官網教程4 路由
前面的章節我們建立了乙個簡單的日誌系統,可以把訊息廣播到許多接收者。本節我們將增加乙個特性 只訂閱一部分訊息。比如只把錯誤日誌輸出到檔案,同時把所有日誌輸出到螢幕。繫結 前面的例子裡我們已經建立過繫結。繫結就是交換機和佇列間的一種關係,簡單解讀為佇列關注該交換機的訊息。建立繫結時可以增加乙個引數ro...
ue4 官網IK流程記錄
這裡注意下make vector時把z方向的偏移量設定到了x上 猜測原因是效應器的x方向跟世界座標的z方向相同 這個可以在two bone ik中調整效應器,然後看效應器的位置數值得到驗證 效應器的x軸和世界座標z軸完全對應,是朝上的 但是其他兩個軸和世界座標不對應,是另乙個獨立的相對座標系,應該是...
小鵬汽車官宣 獲小公尺集團戰略投資4億美元
tech程式設計客棧web 程式設計客棧 11 月 13 日,小鵬汽車官微發布訊息,宣布獲得c輪融資 4 億美金,由小公尺集團投資。小鵬汽車在微博中表示,獲小公尺集團戰略投資,共拓智慧型生態領域建設,同時現有股東繼續加持。獲滙豐等多家中外銀行數十億元級授信。創始人何小鵬本人在a b輪基礎上再次加持,...