美文网首页
Swift利用KVO监听数组元素的变化

Swift利用KVO监听数组元素的变化

作者: SevenRain7 | 来源:发表于2017-11-01 11:41 被阅读0次

    一.概述
    KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了。

    二.使用的步骤
    1.注册,指定被观察者和观察的对象

       objectToObserve.addObserver(self, forKeyPath: "contentArray", options: .new, context: &myContext)
    

    2.实现属性变化的回调

      override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
            if context == &myContext {
    
           } else {
                super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
            }
        }
    

    3.移除观察

       deinit {
            objectToObserve.removeObserver(self, forKeyPath: "contentArray", context: &myContext)
        }
    

    三.完整的代码

    @objcMembers class MyObjectToObserve: NSObject {
        dynamic var contentArray = [String]()
    }
    private var myContext = 0
    class PlaySpeechString: NSObject,AVSpeechSynthesizerDelegate {
        static let shared = PlaySpeechString()
        var objectToObserve = MyObjectToObserve()
    
        // Make sure the class has only one instance
        // Should not init or copy outside
        private override init() {
            super.init()
            objectToObserve.addObserver(self, forKeyPath: "contentArray", options: .new, context: &myContext)
        }
        
        override func copy() -> Any {
            return self // SingletonClass.shared
        }
        
        override func mutableCopy() -> Any {
            return self // SingletonClass.shared
        }
        
        override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
            if context == &myContext {
    
            } else {
                super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
            }
    
        }
    
        deinit {
            objectToObserve.removeObserver(self, forKeyPath: "contentArray", context: &myContext)
            }
        }
    

    注意:
    1.被观察属性所在的类需要用 @objcMembers 关键字修饰 要不会报error
    fatal error: Could not extract a String from KeyPath
    Swift.ReferenceWritableKeyPath
    2.被观察的属性需要用dynamic修饰,否则也无法观察到。

    相关文章

      网友评论

          本文标题:Swift利用KVO监听数组元素的变化

          本文链接:https://www.haomeiwen.com/subject/agvwpxtx.html