KVO:如何在Swift中的observeValue(forKeyPath:…)中获取旧值/新值?

我用.Old |创建了一个观察者.新的选择.在handler方法中,我尝试在值之后获取,但编译器抱怨:’NSString’不能转换为’NSDictionaryIndex:NSObject,AnyObject
override func observeValueForKeyPath(keyPath: String!,ofObject object: AnyObject!,change: [NSObject : AnyObject]!,context: UnsafeMutablePointer<Void>) {

    let approvedOld = change[NSKeyValueChangeOldKey] as Bool
    let approvedNew = change[NSKeyValueChangeNewKey] as Bool
iOS 11和Swift> 4.1

iOS 11和Swift 4为KVO带来了重大变化.

>类应采用@objcMembers注释,以便使KVO或KVO无声地失败.
>必须将要观察的变量声明为动态.

这是更新的实现,

@objcMembers
class Approval: NSObject {

    dynamic var approved: Bool = false

    let ApprovalObservingContext = UnsafeMutableRawPointer(bitPattern: 1)

    override init() {
        super.init()

        addObserver(self,forKeyPath: #keyPath(approved),options: [.new,.old],context: ApprovalObservingContext)
    }

    override func observeValue(forKeyPath keyPath: String?,of object: Any?,change: [NSKeyValueChangeKey : Any]?,context: UnsafeMutableRawPointer?) {
        guard let observingContext = context,observingContext == ApprovalObservingContext else {
                super.observeValue(forKeyPath: keyPath,of: object,change: change,context: context)
                return
        }

        guard let change = change else {
            return
        }

        if let oldValue = change[.oldKey] {
            print("Old value \(oldValue)")
        }

        if let newValue = change[.newKey]  {
            print("New value \(newValue)")
        }

    }

    deinit {
        removeObserver(self,forKeyPath: #keyPath(approved))
    }
}

KVO还有一个新的基于bock的api,就像这样工作,

@objcMembers
class Approval: NSObject {

    dynamic var approved: Bool = false

    var approvalObserver: NSKeyValueObservation!

    override init() {
        super.init()
        approvalObserver = observe(\.approved,.old]) { _,change in
            if let newValue = change.newValue {
                print("New value is \(newValue)")
            }

            if let oldValue = change.oldValue {
                print("Old value is \(oldValue)")
            }
        }

    }
}

基于块的api看起来超级好用且易于使用.此外,KeyValueObservation在deinited时无效,因此不需要删除观察者.

Swift 2.0和iOS< 10 使用Swift 2.0,这是一个使用KVO的类的完整实现,

class Approval: NSObject {

    dynamic var approved: Bool = false

    let ApprovalObservingContext = UnsafeMutablePointer<Int>(bitPattern: 1)

    override init() {
        super.init()
        addObserver(self,forKeyPath: "approved",options: [.Old,.New],context: ApprovalObservingContext)
    }

    override func observeValueForKeyPath(keyPath: String?,ofObject object: AnyObject?,change: [String : AnyObject]?,context: UnsafeMutablePointer<Void>) {

        if let theChange = change as? [String: Bool] {

            if let approvedOld = theChange[NSKeyValueChangeOldKey]  {
                print("Old value \(approvedOld)")
            }

            if let approvedNew = theChange[NSKeyValueChangeNewKey]{
                print("New value \(approvedNew)")

            }

            return
        }
        super.observeValueForKeyPath(keyPath,ofObject: object,context: context)
    }

    deinit {
        removeObserver(self,forKeyPath: "approved")
    }
}

let a  = Approval()
a.approved = true

相关文章

Swift 正式开源!Swift 团队很高兴宣布 Swift 开始开源新篇章。自从苹果发布 Swfit 编程语言,就成为了...
快,快,快!动动您的小手,分享给更多朋友! 苹果去年推出了全新的编程语言Swift,试图让iOS开发更简单...
开发者(KaiFaX) 面向开发者、程序员的专业平台! 和今年年初承诺的一样,苹果贴出了Swift语言的源码,...
本文由@Chun发表于Chun Tips :http://chun.tips/blog/2014/12/11/shi-yong-swift-gou-jian-zi-ding-yi...
本文由CocoaChina译者leon(社区ID)翻译 原文:THE RIGHT WAY TO WRITE A SINGLETON 在之前的帖子里聊过...
本文由CocoaChina译者leon(社区ID)翻译 原文:THE RIGHT WAY TO WRITE A SINGLETON 在之前的帖子里聊过...