2017-05-14 8 views
0

私は、アプリの一部を書き換えて、このコードを見つけています:SwiftのUserDefaultsにKVOを使用するには?

fileprivate let defaults = UserDefaults.standard 

func storeValue(_ value: AnyObject, forKey key:String) { 
    defaults.set(value, forKey: key) 
    defaults.synchronize() 

    NotificationCenter.default.post(name: Notification.Name(rawValue: "persistanceServiceValueChangedNotification"), object: key) 
} 
func getValueForKey(_ key:String, defaultValue:AnyObject? = nil) -> AnyObject? { 
    return defaults.object(forKey: key) as AnyObject? ?? defaultValue 
} 

私はsynchronizeは廃止予定されていることがわかりdefaults.synchronize()ラインをCMD-クリックします。これは、コードで書かれている:他のユーザーに通知するために、書き込み後を同期:

/*! 
    -synchronize is deprecated and will be marked with the NS_DEPRECATED macro in a future release. 

    -synchronize blocks the calling thread until all in-progress set operations have completed. This is no longer necessary. Replacements for previous uses of -synchronize depend on what the intent of calling synchronize was. If you synchronized... 
    - ...before reading in order to fetch updated values: remove the synchronize call 
    - ...after writing in order to notify another program to read: the other program can use KVO to observe the default without needing to notify 
    - ...before exiting in a non-app (command line tool, agent, or daemon) process: call CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication) 
    - ...for any other reason: remove the synchronize call 
    */ 

は、私の知る限りが解釈できるように、私の場合での使用は、第二の記述に適合します。

これはovserveにKVOを使用することを示唆していますが、どのようにですか?私がこれを検索すると、少し古いObjective-C-examplesの束が見つかります。 UserDefaultsを観察するためのベストプラクティスは何ですか?

+0

http://stackoverflow.com/a/28744491/1419216多分あなたが探しているもの。 –

+0

あなたは 'UserDefaults.didChangeNotification'にオブザーバーを追加できます –

答えて

0

デビッド・スミスのブログ http://dscoder.com/defaults.html https://twitter.com/catfish_man/status/674727133017587712

から一つのプロセスが共有デフォルトを設定した場合、その後、あなたは非常にいくつか残っている状況のいずれであってもよく、それを読んで に別のプロセスを通知 -synchronizeメソッドを呼び出すと便利です:-synchronizeは を「バリア」として動作させます。 が返されると、そのデフォルトを読み取る他のプロセスには、新しい の値が表示されます。古い値。 iOSの9.3 上で実行中のアプリケーションの場合

以降/ MacOSのシエラ以降、-synchronize必要とされていない(または 推奨)も、このような状況では、 デフォルトのキーと値の観察は今のプロセス間で機能するので、そう読み取りプロセスはちょうど 値を変更するために直接見ることができます。その結果、これらのオペレーティングシステムで実行されている のアプリケーションは、一般的に決して 呼び出しを同期する必要はありません。

ほとんどの場合、同期を呼び出すように設定する必要はありません。それはKVOによって自動的に処理されます。

persistanceServiceValueChangedNotification通知を処理しているクラスにオブザーバを追加する必要があります。あなたはまた、deinit

であなたのオブザーバーを削除

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

    //do your changes with for key 
} 

をオブザーバーハンドルviewDidLoadなど

UserDefaults.standard.addObserver(self, forKeyPath: "myKey", options: NSKeyValueObservingOptions.new, context: nil) 

かもしれあなたのクラスにオブザーバーを追加

名「MYKEY」とキーを設定しているとしましょう

2

iOS 11 + Swift 4では、推奨方法(SwiftLintによる)はブロックベースのKVO APIを使用しています。

例:

のは、私は私のユーザデフォルトに格納された整数値を持っており、それがgreetingsCountと呼ばれていましょう。

まず私はUserDefaultsを拡張する必要があります。

extension UserDefaults { 
    @objc dynamic var greetingsCount: Int { 
     return integer(forKey: "greetingsCount") 
    } 
} 

これは私たちが後でこのように、観察するためのキーのパスを定義することができます:

var observer: NSKeyValueObservation? 

init() { 
    observer = UserDefaults.standard.observe(\.greetingsCount, options: [.initial, .new], changeHandler: { (defaults, change) in 
     // your change logic here 
    }) 
} 

、決してクリーンアップするのを忘れ:

deinit { 
    observer?.invalidate() 
} 
関連する問題