2017-12-06 8 views
1

SwiftのシングルトンプロパティでKVCを使用することが可能かどうかについて私の質問がありました。私はクラスでKVCをテストしていましたが、クラスを動作させることができましたが、それがSingletonクラスで動作するかどうかを確認することに決めました。
私のシングルトンの "共有"プロパティがKVCに準拠していないというエラーが発生しました。シングルトンパターンでKVCを使用する

class KVOObject: NSObject { 
    @objc static let shared = KVOObject() 
    private override init(){} 

    @objc dynamic var fontSize = 18 
} 

override func viewDidLoad() { 
    super.viewDidLoad() 

    addObserver(self, forKeyPath: #keyPath(KVOObject.shared.fontSize), options: [.old, .new], context: nil) 
} 

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { 
    if keyPath == #keyPath(KVOObject.shared.fontSize) { 
     // do something 
    } 
} 

私は現在、下のエラーを取得しています:

NetworkCollectionTest [9714:452848] ***キャッチされない例外により 'NSUnknownKeyException'、理由にアプリを終了:「[addObserver:forKeyPath:共有 "@。 fontSize "options:3 context:0x0]"共有 "プロパティでKVCに準拠していないオブジェクトに送信されました。

+1

キーパスは '#keyPath(KVOObject.fontSize)'ですか? – Rob

+0

'#keyPath(KVOObject.fontSize) 'を使っても動作しますが、' KVOObject.shared.fontSize'というプロパティが変更されても、それは観測されません。 – victorydub

+0

これは機能します!ありがとう – victorydub

答えて

1

キーパスが正しくありません。それはKVOObject.fontSizeです。そして、あなたはそのシングルトンにオブザーバーを追加する必要があります:あなたはおそらく、あなたがこれを処理しているかどうか、で使用されるかもしれないかどうかを識別するためにコンテキストを使用する必要があります(a)は余談として

KVOObject.shared.addObserver(self, forKeyPath: #keyPath(KVOObject.fontSize), options: [.old, .new], context: nil) 

、スーパークラス; (b)自分のものでない場合は、superの実装に電話する必要があります。そして、、(c)deinitにオブザーバーを削除することを確認してください:それは閉鎖ベース(コンテキストの必要性を回避)だと自動的に削除されるようスウィフト4で、それは今はるかに簡単だ場合、

class ViewController: UICollectionViewController { 

    private var observerContext = 0 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     KVOObject.shared.addObserver(self, forKeyPath: #keyPath(KVOObject.fontSize), options: [.new, .old], context: &observerContext) 
    } 

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

    deinit { 
     KVOObject.shared.removeObserver(self, forKeyPath: #keyPath(KVOObject.fontSize)) 
    } 

    ... 
} 

のとき、またはNSKeyValueObservation滝範囲外:

関連する問題