簡體   English   中英

KVO和Swift 3.0:如何評估更改字典?

[英]KVO and Swift 3.0: How to evaluate the change dictionary?

我試圖弄清楚如何評估func observeValue(forKeyPath...[NSKeyValueChangeKey : AnyObject]更改字典參數func observeValue(forKeyPath...我在操場上有以下代碼,我正在評估更改字典的方式我總是想到更改是NSKeyValueChange.setting(這絕對是錯誤的)。

評估變更字典的正確方法是什么?

import Foundation

class KVOTester: NSObject {

  dynamic var items = [Int]()   // Observe via KVO

  override init() {
    super.init()

    self.addObserver(self, forKeyPath: #keyPath(KVOTester.items), options: [], context: nil)
  }

  deinit {
    self.removeObserver(self, forKeyPath: #keyPath(KVOTester.items))
  }

  func exerciseKVO() {
    self.items = [Int]()      // NSKeyValueChange.setting
    self.items.append(1)      // NSKeyValueChange.insertion
    self.items[0] = 2         // NSKeyValueChange.replacement
    self.items.remove(at: 0)  // NSKeyValueChange.removal
  }

  override func observeValue(forKeyPath keyPath: String?, of object: AnyObject?, change: [NSKeyValueChangeKey : AnyObject]?, context: UnsafeMutablePointer<Void>?) {

    // We are only interested in changes to our items array
    guard keyPath == "items" else { return }

    // #1: object is the KVOTester instance - why isn't it the items array?

    // #2 I don't understand how to use the change dictionary to determine what type of change occurred. The following
    //    is wrong - it *always* prints "Setting".
    if let changeKindValue = change?[.kindKey] as? UInt, changeType = NSKeyValueChange(rawValue: changeKindValue) {
      switch changeType {
      case .setting:
        print("Setting")
        break
      case .insertion:
        print("Insertion")
        break
      case .removal:
        print("Removal")
        break
      case .replacement:
        print("Replacement")
        break
      }
    }
  }
}

let kvoTester = KVOTester()
kvoTester.exerciseKVO()

正如原始提問者在評論中指出的那樣,以下代碼將給出預期結果:

import Foundation

class KVOTester: NSObject {

    dynamic var items = [Int]() // Observe via KVO

    override init() {
        super.init()

        self.addObserver(self, forKeyPath: #keyPath(KVOTester.items), options: [], context: nil)
    }

    deinit {
        self.removeObserver(self, forKeyPath: #keyPath(KVOTester.items))
    }

    func exerciseKVO() {

        let kvoArray = self.mutableArrayValue(forKey: #keyPath(KVOTester.items))

        items = [Int]()                         // NSKeyValueChange.setting
        kvoArray.add(1)                         // NSKeyValueChange.insertion
        kvoArray.replaceObject(at: 0, with: 2)  // NSKeyValueChange.replacement
        kvoArray.removeObject(at: 0)            // NSKeyValueChange.removal
    }

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {

        // We are only interested in changes to our items array
        guard keyPath == "items" else { return }

        if  let changeKindValue = change?[.kindKey] as? UInt,
            let changeType = NSKeyValueChange(rawValue: changeKindValue) {

            switch changeType {
            case .setting:
                print("Setting")
                break
            case .insertion:
                print("Insertion")
                break
            case .removal:
                print("Removal")
                break
            case .replacement:
                print("Replacement")
                break
            }
        }
    }
}

let kvoTester = KVOTester()
kvoTester.exerciseKVO()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM