在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Android/ Swift 響應(yīng)式編程
101 種讓你的網(wǎng)頁看起來更酷的方法
Android 項目是如何使用 Kotlin 語言生成的 1/2
Nimbledroid 版本更新
使用TypeScript提高開發(fā)能力
利用 TensorFlow Serving 系統(tǒng)在生產(chǎn)環(huán)境中運行模型
Google Play 榜單APP冷啟動速度分析報告
使用微信控制電腦(Python 版)
jQuery 3 中的新變動
RxAndroid 基礎(chǔ):第一部分
Swift in 2016
UI自動化測試基于Activity的封裝模式
2016年,有哪些適合你學(xué)習(xí)的編程語言?
Swift 響應(yīng)式編程
如何組合使用 VIM 編輯器與 IPYthon
如何使你的app更加流暢
介紹用來選擇輪廓圖像的一個類——Will J Miller
關(guān)于Android N 開發(fā)者預(yù)覽版的一些隨想

Swift 響應(yīng)式編程

譯者:李鑫

原文:REACTIVE PROGRAMMING IN SWIFT

本文為極客學(xué)院Wiki組織翻譯,轉(zhuǎn)載請注明出處。

時間:2016.3.4

本文將介紹一個響應(yīng)式編程架構(gòu) RxSwift,并結(jié)合使用 Swift 的函數(shù)式功能來編寫更簡潔、更表現(xiàn)力的代碼,從而管理應(yīng)用狀態(tài)及并行任務(wù)。

Swift 及其函數(shù)式功能

Swift 可被認為是一種現(xiàn)代的面向?qū)ο笳Z言,對泛型編程有著原生支持。雖然它不是一種函數(shù)式語言,但其中的一些特性卻可以讓我們利用函數(shù)式方式來編程,比如可以利用閉包first-class 類型函數(shù),以及不可變的value 類型

然而,Cocoa Touch 是一個面向?qū)ο蟮募軜?gòu),有著這一范式所強制的約束。軟件開發(fā)中常見的問題在于如何管理共享應(yīng)用狀態(tài)以及異步數(shù)據(jù)的并行任務(wù)。

函數(shù)式編程解決這些問題的辦法是,賦予不可變狀態(tài)一定的特權(quán),以及將應(yīng)用邏輯定義為不會在應(yīng)用生存周期內(nèi)改變的表達式。通過定義自包含的函數(shù),并行化計算就會變得簡單,最大程度減少并發(fā)問題。

響應(yīng)式模型

響應(yīng)式編程根源于 FRP(函數(shù)響應(yīng)式編程)命令驅(qū)動的編程方式,是以異步數(shù)據(jù)流的形式進行編程。

這可能有些難懂,所以最好通過一個簡單的例子來大體了解一下。

表達一個變量間關(guān)系

假如有 2 個變量(A 和 B),它們的值會在應(yīng)用運行時中經(jīng)常改變。還有一個變量(C),它的值取決于前兩個變量值。

2. var B = 20
3. let C = A * 2 + B
4. 
5. // 當(dāng)前值
6. // A = 10, B = 20, C = 40
7. 
8. A = 0
9.
10. // 當(dāng)前值
11. // A = 0, B = 20, C = 40  

C 值與 A 和 B 有關(guān),B 只被當(dāng) A 和 B 的賦值操作執(zhí)行后,它們?nèi)咧g的關(guān)系很快就解散了。這時再改變 A 與 B 的值,將不會對 C 的值有任何影響。

所以,在任何指定時間,要想計算表達式,就必須根據(jù) A 和 B 的當(dāng)前值,重新指定 C 值,重新計算。

用響應(yīng)式編程方式該怎么做呢?

采用響應(yīng)式模式,我們將創(chuàng)建兩個流,來傳遞 A 或 B 值的改變。

一般可使用彈珠圖來展示這個原理。如下圖所示,每一行表示連續(xù)的一段時間,每一個彈珠表示發(fā)生在特定時刻的一個事件。

彈珠圖

Cocoa Touch 中的做法

在 Cocoa Touch 中,使用鍵值對觀察,為發(fā)生改變的變量添加觀察者,當(dāng) KVO 系統(tǒng)通知時再進行處理。

self.addObserver(self, forKeyPath:"valueA", options: .New, context: nil)
self.addObserver(self, forKeyPath:"valueB", options: .New, context: nil)

override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
    let C = valueA * 2 + valueB
}

如果變量與用戶界面相連,那么可以在 UIKit 中定義一個當(dāng)觸發(fā)變化事件時即被調(diào)用的處理器:

sliderA.addTarget(self, action: "update", forControlEvents: UIControlEvents.ValueChanged)
sliderB.addTarget(self, action: "update", forControlEvents: UIControlEvents.ValueChanged)

func update() {
    let C = sliderA.value * 2 + sliderB.value
}  

但是,對于調(diào)用的變量、它們的生存周期以及改變它們值的事件,以上兩種方法都沒有定義一種持久、顯式的關(guān)系。

我們可以用響應(yīng)式編程模式來處理這種情況。當(dāng)前對于 OS X 和 iOS 開發(fā)者而言,有多種不同的實現(xiàn),比如 RxSwiftReactiveCocoa。

下面簡單介紹一下 RxSwift,不過這兩種架構(gòu)的概念是相似的。

RxSwift

RxSwift 繼承自觀察者模式,模擬 Cocoa Touch 對象中的異步數(shù)據(jù)流,按通常的集合來看待這些對象。通過利用可觀測流繼承一些 Cocoa Touch 類,可以訂閱它們的輸出,并利用復(fù)合運算(如 filter()、merge()map()reduce() 等)來使用這些輸出。

還回到剛才的例子中,假設(shè)一個 iOS 應(yīng)用有兩個滑塊(sliderA 和 sliderB),并希望利用之前的表達式(A * 2 + B)不斷更新標(biāo)簽(labelC)的值:

1. combineLatest(sliderA.rx_value, sliderB.rx_value) {
2.      $0 * 2 + $1
3. }.map {
4.      "Sum of slider values is \($0)"
5.  }.bindTo(labelC.rx_text)

利用 UISlider 類的 rx_value 后綴,將滑塊的值屬性轉(zhuǎn)化為可觀測類型,
通過在每個滑塊的可觀測類型上使用 combineLatest() 操作,我們還創(chuàng)建了一種新的可觀測類型,只要其中任何一個源流釋放出一個項目,它就會釋放項目。結(jié)果就是一個元組,每個滑塊值都可以通過操作回調(diào)而轉(zhuǎn)換(代碼行 2)。然后將變換值映射到信息性字符串(代碼行 4),并將其值綁定到標(biāo)簽上(代碼行 5)。

通過組合 3 個獨立的操作(combineLatest()map()、bindTo()),我們就能精確地表達三種對象之間的關(guān)系并不斷更新應(yīng)用的 UI,響應(yīng)應(yīng)用狀態(tài)中的改變。

Sum_of_slider_values

額外介紹

上面的內(nèi)容只是對 RxSwift 用途做了一個粗淺的介紹。

參看樣例代碼,在這個例子中,使用可鏈接的異步任務(wù)下載在線資源。如果這篇文章引發(fā)了你的好奇心,一定要看看這個例子。

然后,可以讀讀這篇文檔,學(xué)習(xí)其他一些 API 擴展,采用一種函數(shù)式并具有表現(xiàn)力的方式來開發(fā) iOS 應(yīng)用。

還可閱讀 使用輕量級模式 來了解Swift 模式如何幫助你處理大量相似對象。

作者簡介

Milton Moura(@mgcm)是一位葡萄牙的自由 iOS 開發(fā)者。他曾就職于涉及航空、電信、能源等領(lǐng)域的多家公司,如今全心致力于使用蘋果技術(shù)開發(fā)優(yōu)秀應(yīng)用。除了醉心于設(shè)計與用戶交互外,他還非常喜歡新的軟件開發(fā)方式。其博客為:http://defaultbreak.com