2009-07-17 15 views
50

Diciamo che ho una chiave @ "MyPreference", con un valore corrispondente memorizzato tramite NSUserDefaults.Cacao - Notifica sulla modifica del valore di NSUserDefaults?

C'è un modo per essere avvisati quando il valore viene modificato?

Oppure potrebbe essere eseguito tramite attacchi? (Ma in questo caso, invece di legare il valore a un elemento dell'interfaccia utente, desidero che il mio oggetto venga informato della modifica, in modo da poter eseguire altre attività.)

Sono consapevole che NSUserDefaultsDidChangeNotification può essere osservato, ma questo sembra essere un approccio tutto-o-niente, e non sembra esserci un meccanismo per arrivare alla coppia chiave-valore specifica che è stata modificata. (. Sentitevi liberi di correggere)

risposta

77

trascorso tutta la giornata a cercare la risposta, solo per scoprire che 10 minuti dopo aver chiesto la questione ...

sono imbattuto in una soluzione attraverso Key-Value-Observing:

[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self 
    forKeyPath:@"values.MyPreference" 
    options:NSKeyValueObservingOptionNew 
    context:NULL]; 

O, più semplicemente (per commento qui sotto):

[[NSUserDefaults standardUserDefaults] addObserver:self 
             forKeyPath:@"MyPreference" 
              options:NSKeyValueObservingOptionNew 
              context:NULL]; 
+14

Si potrebbe anche chiamare questo metodo in '[NSUserDefaults standardUserDefaults]' e non dover anteporre i "valori". al percorso chiave. Gli altri parametri rimangono invariati. –

+6

Non ero in grado di farlo funzionare come Quin suggeriva di usare '[NSUserDefaults standardUserDefaults]'. Tuttavia, la stringa append non è necessaria poiché '... forKeyPath: @" values.MyPreference "...' funzionerà. Inoltre, è necessario implementare '- (void) observValueForKeyPath: (NSString *) keyPath ofObject: (id) modifica dell'oggetto: (NSDictionary *) modifica contesto: (void *) contesto;' per acquisire effettivamente l'evento. – TrevorL

+0

Hi TrevorL ... anche se stringByAppendingString: non è necessario, aiuta quando si crea un metodo generico - (void) observPreference: (NSString *) pref {... [@ "valori." stringByAppendingString: pref] ... – Arvin

9

E dipendente di Apple consiglia di utilizzare la notifica NSUserDefaultsDidChangeNotification qui: https://devforums.apple.com/message/237718#237718

+6

Lo svantaggio di questo è, non puoi sapere quale delle impostazioni è stata cambiata. – Emmanuel

+2

Sì, penseresti che avrebbero inserito almeno le chiavi modificate nel dizionario userInfo di NSUserDefaultsDidChangeNotification, ma no: "Questa notifica non contiene un dizionario userInfo."Peggio ancora, l'unica specifica di quando NSUserDefaultsDidChangeNotification viene pubblicata dice che è pubblicato" quando un dominio persistente è cambiato ". Probabilmente mi ci vorranno 20 minuti di ricerca per confermare esattamente cosa significa, e quindi non sono sicuro di fidatevi di questo: –

13

Swift:

override func viewDidLoad() { 
    super.viewDidLoad() 
    NSUserDefaults.standardUserDefaults().addObserver(self, forKeyPath: "THE KEY", options: NSKeyValueObservingOptions.New, context: nil) 
} 

override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) { 
    // your logic 
} 

deinit { 
    NSUserDefaults.standardUserDefaults().removeObserver(self, forKeyPath: "THE KEY") 
} 
+0

non dimenticate di rimuovere l'osservatore poiché state spiegando l'approccio completo – slxl

0

Sono d'accordo con @DenNukem. Stavo usando NSKeyValueObservingOptionNew. Ma questa funzione ha iniziato a darmi il codice BADACCESS = 1 errore ovunque io abbia usato NSUserdefault per salvare altri oggetti. Nel caso tu stia utilizzando Key Value Observer, tieni presente il problema Zombie su NSUserDefaults.

ecco il link alla soluzione: NSUserDefaults and KVO issues

Problemi correlati