今日分享-Swift之KVO

說到KVO,IOS開發者肯定都不陌生,尤其對使用oc開發的同學,更爲熟悉,接下來先回顧下oc中的KVO.

KVO:鍵值觀察機制,提供了觀察某一屬性變化的方法,極大的簡化了代碼。作爲一種設計模式,它被這樣介紹。它與KVC之間的關係這裏不在贅述,有興趣的同學可以去了解一下。
先來看一段代碼:

//添加監聽者
[self.scrollview addObserver: self forKeyPath: @"contentOffset" options: NSKeyValueObservingOptionNew context: nil];

這段代碼監聽了scrollview的contentOffset 屬性變化,Observer 觀察者爲 self(即爲自己的控制器),NSKeyValueObservingOptionNew 爲監聽屬性變化後的新值 context 環境變量這裏置爲 nil。在進入控制器的合適時機添加監聽


/**
 *  監聽屬性值發生改變時回調
 */
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
  if change[NSKeyValueObservingOptionNew] > 0 {
  CGFloat offset = self.tableView.contentOffset.y;
    CGFloat delta = offset / 64.f + 1.f;
    delta = MAX(0, delta);
    [self alphaNavController].barAlpha = MIN(1, delta);
  }  
}

這段代碼爲響應監聽,處理事件的回調方法,對應上段代碼 KeyPath 監聽的屬性,object爲被監聽的對象 scrollview,change 爲 NSKeyValueObservingOptionNew屬性的值,context 爲環境變量 nil。在控制器內任意位置實現這個方法


[self.scrollview removeObserver:self forKeyPath:@"contentOffset" context:nil];

在控制器銷燬前務必要執行這段removeObserver代碼

接下來看KVO在Swift中的用法

class ReadCourse: NSObject {
    dynamic var id : Int = 0
 }
var observecourse = ReadCourse()  
var player = AVPlayer() //這裏簡單描述observecourse,player兩個屬性,不代表項目裏要這樣創建

player.addObserver(self, forKeyPath: "rate", options: NSKeyValueObservingOptions.new, context: nil)

observecourse.addObserver(self, forKeyPath: "id", options: [NSKeyValueObservingOptions.new , NSKeyValueObservingOptions.old], context: nil)
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {

        if keyPath == "rate" {
            if self.player.rate == 0 {
                self.playAndPauseBtn.isSelected = true
            }else{
                self.playAndPauseBtn.isSelected = false
            }
        }else if keyPath == "id" {
            let new = change?[NSKeyValueChangeKey.newKey]
            let old = change?[NSKeyValueChangeKey.oldKey]
            if new as! Int != old as! Int {
                loadData()
            }
        }
    }

上面代碼中監聽了 player 的 rate 屬性,observecourse 的 id 屬性。你可能注意到 id 屬性前的 dynamic 的字段。1.Swift中屬性前不添加 dynamic 字段,是無法觀察到屬性的變化的並且。2.Swift中觀察者和被觀察者都必須繼承與NSObject
具體原因參考這篇文章:這裏鏈接內容

今日分享就到這裏,有什麼不明白或者錯誤可在評論區留言,喜歡的加個關注,下期再見!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章