RxSwift使用初體驗(yàn)

最近有幸學(xué)習(xí)了一下RxSwift框架,突然有了一種發(fā)現(xiàn)新大陸的感覺,雖然之前也一直在用OC的RAC框架,但是在Swift開發(fā)中RxSwift真的是iOS開發(fā)者的利器,后悔沒有早點(diǎn)接觸,特此記錄一下。
官網(wǎng)地址

1、RxSwift導(dǎo)入

話不多說,直接上實(shí)操:
使用pods直接install最新的庫,cocoapods安裝就不說了,參考:cocoapods詳解

target 'YOUR_TARGET_NAME' do
    pod 'RxSwift', '6.5.0'
    pod 'RxCocoa', '6.5.0'
end

2、RxSwift簡單使用

import RxSwift
import RxCocoa

KVO使用

正常操作需要三步,1、添加觀察者對象 2、實(shí)現(xiàn)監(jiān)聽方法 3、銷毀觀察者

    // 添加觀察者對象
    func setupKVO() {
        self.person.addObserver(self, forKeyPath: "name", options: .new, context: nil)
    }
    // 實(shí)現(xiàn)監(jiān)聽方法
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        print("響應(yīng)")
        print(change as Any)
    }
    // 銷毀觀察者
    deinit {
        self.removeObserver(self.person, forKeyPath: "name", context: nil)
    }

相對來說,用rxSwift實(shí)現(xiàn),一步到位,代碼簡潔,模塊功能劃分清晰,不用這邊寫一個那邊寫一個,增加代碼可讀性和可維護(hù)性

func setupKVO() {
    self.person.rx.observeWeakly(String.self, "name")
            .subscribe { value in
                print(value as Any)
            }
            .disposed(by: disposeBag) 
}

UIButton使用

UIButton我們平時(shí)使用也是一樣,點(diǎn)擊事件需要addTarget,然后在某一個地方,實(shí)現(xiàn)點(diǎn)擊事件函數(shù);
同樣的,用RxSwift也是一目了然。

//        self.button.addTarget(self, action: #selector(<#T##@objc method#>), for: .touchUpInside)
        self.button.rx.controlEvent(.touchUpInside)
            .subscribe { _ in
                print("點(diǎn)擊事件") 
            }
            .disposed(by: disposeBag)

UITextField

func setupTextFiled() {
        self.textFiled.rx.text.orEmpty.changed
            .subscribe { text in
                print(text)
            }
            .disposed(by: disposeBag)
    }

同時(shí)textFiled也可以跟button進(jìn)行雙向綁定,輸入文字同步修改按鈕的值,也可以根據(jù)輸入文字長度,動態(tài)變更按鈕狀態(tài);
這個bind確實(shí)很好用,讓我想起之前做前端開發(fā)的時(shí)候,用的vue框架,v-bind,v-on,無需關(guān)心邏輯代碼,專心寫好業(yè)務(wù)代碼就好,簡直不要太爽

self.textFiled.rx.text
            .bind(to: self.button.rx.title())
            .disposed(by: disposeBag)
            
// 根據(jù)輸入文字長度,動態(tài)變更按鈕狀態(tài)
let isEnabled = textFiled.rx.text.orEmpty
            .map { text in
                return text.count >= 6
            }
        isEnabled.bind(to: button.rx.isEnabled)
            .disposed(by: disposeBag)

UIScrollView

UIScrollView的用法同樣也可以訂閱我們想要的內(nèi)容,比如監(jiān)聽contentOffset變化,平時(shí)我們可能要設(shè)置delegate,然后在遵循方法,修改等等,使用rx就是一步到位,比如我們常見的向下滾動,導(dǎo)航欄透明,一行代碼就可以搞定;

func setupScrollerView() {
        scrollView.rx.contentOffset
            .subscribe { [weak self]content in
                self?.titleView.alpha = (100-content.y)/(100)
            }
            .disposed(by: disposeBag)
    }

手勢

手勢用起來同樣也很簡單,直接rx.event就可以

func setupGestureRecognizer() {
        let tap = UITapGestureRecognizer()
        self.label.addGestureRecognizer(tap)
        self.label.isUserInteractionEnabled = true
        tap.rx.event.subscribe { tap in
            print(tap.view!)
        }
        .disposed(by: disposeBag)
    }

通知

func setupNotification() {
        NotificationCenter.default.rx.notification(UIResponder.keyboardWillShowNotification)
            .subscribe { noti in
                print(noti)
            }
            .disposed(by: disposeBag)
    }

網(wǎng)絡(luò)請求

網(wǎng)絡(luò)請求步驟其實(shí)沒有比之前簡化多少,只是它幫我們做了處理,成功失敗都有區(qū)分開,無需再判斷是否有error,只關(guān)心業(yè)務(wù)實(shí)現(xiàn)就可以

func setupNetwork() {
        let url = URL(string: "https://www.baidu.com")
        // 正常的網(wǎng)絡(luò)請求步驟
//        URLSession.shared.dataTask(with: url!) { data, response, error in
//            print(String.init(data: data!, encoding: .utf8)!)
//        }.resume()
         
       URLSession.shared.rx.response(request: URLRequest(url: url!))
            .subscribe(onNext: { response, data in
                print(response)
            }, onError: { error in
                print(error)
            })
            .disposed(by: disposeBag)

    }

定時(shí)器

這個定時(shí)器就比較有點(diǎn)不同了,實(shí)際上是個可觀察序列,給這個序列添加subscribe訂閱回調(diào),一秒回調(diào)一次

func setupTimer() {
        timer = Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
        timer.subscribe { num in
            print(num)
        }
        .disposed(by: disposeBag)
    }

有個小細(xì)節(jié)需要注意一下,DisposeBag翻譯過來就是垃圾袋的意思,回收rx開辟的內(nèi)存的地方,如果使用局部變量DisposeBag(),容易出錯,可能函數(shù)出棧就被釋放掉了,導(dǎo)致rx真正要釋放時(shí),沒有DisposeBag可以用;建議一個類對象里面共用一個disposeBag全局變量,當(dāng)前對象被銷毀,它也跟著被釋放,

let disposeBag = DisposeBag()

// DisposeBag() 容易出問題
URLSession.shared.rx.response(request: URLRequest(url: url!))
            .subscribe { response, data in
                print(response)
            }
            .disposed(by: DisposeBag())

3、總結(jié)

像RxSwift這種函數(shù)響應(yīng)式框架其實(shí)在OC、Swift中都很常見,常見的比如Masonry,這種代碼的書寫可讀性、清晰度、可維護(hù)性都很高,當(dāng)然OC中的RAC跟RxSwift是有異曲同工之妙的,可以理解為RxSwift就是Swift版的RAC;

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

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

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