Domanda

Ho dizionario memorizzato nella NSUserDefaults e ho bisogno di aggiungere / rimuovere gli elementi in questo dizionario.

Si preoccupa me che per fare questo devo creare una copia mutevole intero dizionario, modificare un elemento e sostituire l'intera dizionario con nuova copia.

copy = [[defaults objectForKey:@"foo"] mutableCopy];
[copy setObject:… forKey:@"bar"];
[defaults setObject:copy forKey:@"foo"];

e si tratta ancora di più la copia e ri-regolazione per gli oggetti più in profondità nella gerarchia.

C'è un modo migliore?

Ho cercato di utilizzare [defaults setValue:… forKeyPath:@"foo.bar"], ma che non sembra funzionare (oggetto non è mutabile).

È stato utile?

Soluzione

Io di solito creare una classe personalizzata per contenere tutte le mie preferenze dell'applicazione. Quella classe in grado di caricare le copie mutevoli dei userDefaults una volta, quando si avvia il programma, e quindi gestire tutte le incrementale salva lungo il percorso:

MyPreferences.h

@interface MyPreferences
{
   NSMutableDictionary allPrefs;
}
@property (readonly) NSMutableDictionary * allPrefs;
- (void)load;
- (void)save;
@end

MyPreferences.m

@implementation MyPreferences
@synthesize allPrefs;

- (id)init
{
    if ((self = [super init]) == nil) { return nil; }
    allPrefs = [[NSMutableDictionary alloc] initWithCapacity:0];
    return self;
}

- (void)dealloc
{
    [allPrefs release];
    [super dealloc];
}

- (void)load
{
    // load all mutable copies here
    [allPrefs setObject:[[defaults objectForKey:@"foo"] mutableCopy]
                 forKey:@"foo"];
    // ...
}

- (void)save
{
    [defaults setObject:allPrefs forKey:@"app_preferences"];
}

@end

creo un'istanza di questa classe nella mia domanda delegato e quindi chiamare [myPrefs load] quando i miei lanci di applicazione. Le preferenze modificate mentre il programma è in esecuzione può essere modificato attraverso myPrefs, e quindi salvato chiamando [myPrefs save] lo desideri:

MyPreferences * myPrefs = [myApplication myPrefs];
[myPrefs setObject:bar forKeyPath:@"allPrefs.foo.bar"];
[myPrefs save];

Come bonus aggiuntivo, è possibile strutturare la classe MyPreferences come più ti piace, portando i vantaggi della programmazione OO per l'intera serie di preferenze. Ho mostrato la via più facile qui, semplicemente utilizzando un dizionario mutevole, ma si può fare di ogni preferenza in una proprietà, e fare pre / post elaborazione per gli oggetti più complicati come NSColor, per esempio.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top