[轉(zhuǎn)載]為什么要使用 RxSwift ?

為什么要使用 RxSwift ?

我們先看一下 RxSwift 能夠幫助我們做些什么:


Target Action

傳統(tǒng)實現(xiàn)方法:

button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
func buttonTapped() {
    print("button Tapped")
}

通過 Rx 來實現(xiàn):

button.rx.tap
    .subscribe(onNext: {
        print("button Tapped")
    })
    .disposed(by: disposeBag)

你不需要使用 Target Action,這樣使得代碼邏輯清晰可見。


代理

傳統(tǒng)實現(xiàn)方法:

class ViewController: UIViewController {
    ...
    override func viewDidLoad() {
        super.viewDidLoad()
        scrollView.delegate = self
    }
}

extension ViewController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        print("contentOffset: \(scrollView.contentOffset)")
    }
}

通過 Rx 來實現(xiàn):

class ViewController: UIViewController {
    ...
    override func viewDidLoad() {
        super.viewDidLoad()

        scrollView.rx.contentOffset
            .subscribe(onNext: { contentOffset in
                print("contentOffset: \(contentOffset)")
            })
            .disposed(by: disposeBag)
    }
}

你不需要書寫代理的配置代碼,就能獲得想要的結(jié)果。


閉包回調(diào)

傳統(tǒng)實現(xiàn)方法:

URLSession.shared.dataTask(with: URLRequest(url: url)) {
    (data, response, error) in
    guard error == nil else {
        print("Data Task Error: \(error!)")
        return
    }

    guard let data = data else {
        print("Data Task Error: unknown")
        return
    }

    print("Data Task Success with count: \(data.count)")
}.resume()

通過 Rx 來實現(xiàn):

URLSession.shared.rx.data(request: URLRequest(url: url))
    .subscribe(onNext: { data in
        print("Data Task Success with count: \(data.count)")
    }, onError: { error in
        print("Data Task Error: \(error)")
    })
    .disposed(by: disposeBag)

回調(diào)也變得十分簡單


通知

傳統(tǒng)實現(xiàn)方法:

var ntfObserver: NSObjectProtocol!

override func viewDidLoad() {
    super.viewDidLoad()

    ntfObserver = NotificationCenter.default.addObserver(
          forName: .UIApplicationWillEnterForeground,
          object: nil, queue: nil) { (notification) in
        print("Application Will Enter Foreground")
    }
}

deinit {
    NotificationCenter.default.removeObserver(ntfObserver)
}

通過 Rx 來實現(xiàn):

override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.rx
        .notification(.UIApplicationWillEnterForeground)
        .subscribe(onNext: { (notification) in
            print("Application Will Enter Foreground")
        })
        .disposed(by: disposeBag)
}

你不需要去管理觀察者的生命周期,這樣你就有更多精力去關(guān)注業(yè)務(wù)邏輯。


KVO

傳統(tǒng)實現(xiàn)方法:

private var observerContext = 0

override func viewDidLoad() {
    super.viewDidLoad()
    user.addObserver(self, forKeyPath: #keyPath(User.name), options: [.new, .initial], context: &observerContext)
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if context == &observerContext {
        let newValue = change?[.newKey] as? String
        print("do something with newValue")
    } else {
        super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
    }
}

deinit {
    user.removeObserver(self, forKeyPath: #keyPath(User.name))
}

通過 Rx 來實現(xiàn):

override func viewDidLoad() {
    super.viewDidLoad()

    user.rx.observe(String.self, #keyPath(User.name))
        .subscribe(onNext: { newValue in
            print("do something with newValue")
        })
        .disposed(by: disposeBag)
}

這樣實現(xiàn) KVO 的代碼更清晰,更簡潔并且更準確。


多個任務(wù)之間有依賴關(guān)系

例如,先通過用戶名密碼取得 Token 然后通過 Token 取得用戶信息,

傳統(tǒng)實現(xiàn)方法:

/// 用回調(diào)的方式封裝接口
enum Api {

    /// 通過用戶名密碼取得一個 token
    static func token(username: String, password: String,
        success: (String) -> Void,
        failure: (Error) -> Void) { ... }

    /// 通過 token 取得用戶信息
    static func userinfo(token: String,
        success: (UserInfo) -> Void,
        failure: (Error) -> Void) { ... }
}
/// 通過用戶名和密碼獲取用戶信息
Api.token(username: "beeth0ven", password: "987654321",
    success: { token in
        Api.userInfo(token: token,
            success: { userInfo in
                print("獲取用戶信息成功: \(userInfo)")
            },
            failure: { error in
                print("獲取用戶信息失敗: \(error)")
        })
    },
    failure: { error in
        print("獲取用戶信息失敗: \(error)")
})

通過 Rx 來實現(xiàn):

/// 用 Rx 封裝接口
enum Api {

    /// 通過用戶名密碼取得一個 token
    static func token(username: String, password: String) -> Observable<String> { ... }

    /// 通過 token 取得用戶信息
    static func userInfo(token: String) -> Observable<UserInfo> { ... }
}
/// 通過用戶名和密碼獲取用戶信息
Api.token(username: "beeth0ven", password: "987654321")
    .flatMapLatest(Api.userInfo)
    .subscribe(onNext: { userInfo in
        print("獲取用戶信息成功: \(userInfo)")
    }, onError: { error in
        print("獲取用戶信息失敗: \(error)")
    })
    .disposed(by: disposeBag)

這樣你無需嵌套太多層,從而使得代碼易讀,易維護。


等待多個并發(fā)任務(wù)完成后處理結(jié)果

例如,需要將兩個網(wǎng)絡(luò)請求合并成一個,

通過 Rx 來實現(xiàn):

/// 用 Rx 封裝接口
enum Api {

    /// 取得老師的詳細信息
    static func teacher(teacherId: Int) -> Observable<Teacher> { ... }

    /// 取得老師的評論
    static func teacherComments(teacherId: Int) -> Observable<[Comment]> { ... }
}
/// 同時取得老師信息和老師評論
Observable.zip(
      Api.teacher(teacherId: teacherId),
      Api.teacherComments(teacherId: teacherId)
    ).subscribe(onNext: { (teacher, comments) in
        print("獲取老師信息成功: \(teacher)")
        print("獲取老師評論成功: \(comments.count) 條")
    }, onError: { error in
        print("獲取老師信息或評論失敗: \(error)")
    })
    .disposed(by: disposeBag)

這樣你可用寥寥幾行代碼來完成相當復(fù)雜的異步操作。


那么為什么要使用 RxSwift ?

  • 復(fù)合 - Rx 就是復(fù)合的代名詞
  • 復(fù)用 - 因為它易復(fù)合
  • 清晰 - 因為聲明都是不可變更的
  • 易用 - 因為它抽象的了異步編程,使我們統(tǒng)一了代碼風格
  • 穩(wěn)定 - 因為 Rx 是完全通過單元測試的

原文地址:RxSwift-Chinese-Documentation

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 學(xué)習RXSwift比較好的文章:RxSwift 系列(一) -- ObservablesRxSwift 系列(二)...
    努力奔跑的小男孩閱讀 945評論 0 0
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,591評論 19 139
  • 概述 RxSwift顧名思義是Swift的一種框架,您或許曾經(jīng)聽說過「響應(yīng)式編程」(Reactive Progra...
    Mr大喵喵閱讀 2,008評論 3 4
  • 我看我想我說閱讀 164評論 0 0
  • 10組的小伙伴們,大家早上好。俗話說:“緣由心生,隨遇而安。心無掛礙,一切隨緣?!闭嬲Ь壍娜?,會認為它來之不易的...
    13組223魏曉花閱讀 176評論 0 2

友情鏈接更多精彩內(nèi)容