回應式編程已經出了很完整的框架了
比如ReactiveCocoa 簡稱RAC,前段時間有個專案是這個框架(感覺賊雞兒晦澀難懂,完全把編程思路要整個轉換,如果之前不是用這個編程范式),ReactiveCocoa是專門針對的OC Swift,換句話說暫時來說是適配蘋果各平臺開發(iOS,Mac)
再比如ReactiveX,這個這個版本支持的語言就更多了,也不是很重要,就不細較了,唯一值得在意的是RXSwift
use_frameworks!
target 'UItest' do
pod 'RxSwift','~>5'
pod 'RxCocoa','~>5'
end
然后pod install完成第三方庫安裝,這里是用的cocoapods的方式,安裝好了說說
使用教程:
1.匯入
import RxSwift //不包括iOS的任何特性
import RxCocoa //包含iOS UI等一些東西
2.回應式編程的重要角色
Obsevable : 負責發送事件(event)
Observer: 負責訂閱Obsevable,監聽Obsevable發送的事件(我覺得這里應該叫事件佇列,因為很可能是一串資料)
這個程序有點類似于KVO,程序中重要的是事件
public enum Event<Element> {
/// Next element is produced.
case next(Element)
/// Sequence terminated with an error.
case error(Swift.Error)
/// Sequence completed successfully.
case completed
}
RxSwift官方定義事件是個列舉,如上圖,有三個case,可見事件是有三個狀態,1.next攜帶了具體資料,x攜帶的是個Element,這是個泛型,也就是資料型別不定,2.error,是一個錯誤資訊,具體傳出的是Swift.Error ,整個程序會終止,3.completed 這個完成是佇列完成的意思,表示這一個監聽程序整個完成了,并沒有出錯
所以可以確定正常的事件,傳遞的是next,因為2,3顯然說明事件例外終止,或者順利完成
3.基本運用
enum MYError:Error {case test }
let observable = Observable<Int>.create { observer in //創建個 observable
observer.onNext(1) //發送事件
observer.onNext(2)
observer.onNext(3)
observer.onError(MYError.test)
observer.onCompleted()
observer.onNext(4)
return Disposables.create()
}
observable.subscribe { event in //注冊監聽
switch event
{
case .next(let content):
print(content)
case .error(let error):
print(error)
case .completed:
print("完成")
}
}

上述就是RX的基本運用,實戰里面發訊息和接訊息的一般在兩個不同的類,從列印的log也可以看出,不管是onError還是onCompleted(代碼位置有限就沒單獨展示區別),之后就會結束這個回應程序
observable.subscribe { content in
print(content)
} one rror: { error in
print(error)
} onCompleted: {
print("完成")
} onDisposed: {
print("注銷")
}
監聽還有一種方式,區別不是很大,但會多一個注銷,注銷和完成是類似的,區別在于,注銷是由監聽者結束這個回應流程,而Completed是由訊息發送者結束
let disp = observable.subscribe { event in //注冊監聽
switch event
{
case .next(let content):
print(content)
case .error(let error):
print(error)
case .completed:
print("完成")
}
}
disp.dispose()
這是注冊監聽的回傳值,所以注銷的權限是由監聽持有(雖然我這里寫在了一個函式里,實際實戰監聽和發送者肯定不在一起)
let observable = Observable.just(1)
let disp = observable.subscribe { content in
print(content)
} one rror: { error in
print(error)
} onCompleted: {
print("完成")
} onDisposed: {
print("注銷")
}
disp.dispose()
如果不是需要經常發送,也有單次發送
4.UI層面的運用
程式常需要一些計時器之類的東西,比如登錄注冊頁面的短信倒計時,這事解決辦法挺多了,說下RX的解決方式
let observable = Observable<Int>.timer(.seconds(2), period: .seconds(1), scheduler: MainScheduler.instance)
observable.map{"\($0)"}.bind(to: label.rx.text)
需要很復雜的操作,也可以用subscribe函式進行高度自定義,這里就只是展示計時器和bind函式,timer還能用的是兩個函式,一個不需要延時,這個是高度定制的可延時函式,
后面的bind是必須用rx的,這個rx的詳細參見前面的協議編程,里面做過特殊處理的,這里不是直接傳入label.text就可以的
然后UI層面最重要的我感覺就是Binder
let label = UILabel.init(frame: CGRect(x: 0, y: 50, width: UIScreen.main.bounds.width, height: 25))
self.view.addSubview(label)
let binder = Binder<Int>(label, binding: { label, v in
label.text = "剩余" + "\(160 - v)"
})
let _ = Observable<Int>.timer(.seconds(2), period: .seconds(1), scheduler: MainScheduler.instance).subscribe(binder)
具體用法參照代碼
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/301549.html
標籤:其他
