Cancellazione di NSUserDefaults


Risposte:


514

Puoi rimuovere il dominio persistente dell'applicazione in questo modo:

NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];

In Swift 3 e versioni successive:

if let bundleID = Bundle.main.bundleIdentifier {
    UserDefaults.standard.removePersistentDomain(forName: bundleID)
}

Questo è simile alla risposta di @samvermette ma IMO è un po 'più pulito.


Ha funzionato alla grande, grazie! Non dimenticare di rilasciare l'appDomain in seguito.
IcyBlueRose,

15
@IcyBlueRose - bundleIdentifier è un oggetto rilasciato automaticamente poiché non inizia con init o new, quindi si verificherebbe il rilascio eccessivo.
Christopher Rogers,

1
Buono a sapersi, grazie! Ma stavo parlando dell'app StringDomain. Anche quella auto viene rilasciata?
IcyBlueRose,

2
@IcyBlueRose L'oggetto restituito da bundleIdentifier è uguale all'oggetto a cui fa riferimento appDomain.
Christopher Rogers,

2
Non riesco più a farlo funzionare su 10.8, qualcuno potrebbe confermare che funziona? Ecco una domanda correlata SO: stackoverflow.com/questions/13595415/...
DaGaMs

102

Questo codice reimposta le impostazioni predefinite sul dominio di registrazione:

[[NSUserDefaults standardUserDefaults] setPersistentDomain:[NSDictionary dictionary] forName:[[NSBundle mainBundle] bundleIdentifier]];

In altre parole, removeObjectForKeyper ogni singola chiave che tu abbia mai registrato in quell'app.

Riconoscimenti a Ken Thomases su questo thread dei forum degli sviluppatori Apple .


4
Grazie mille. Perché [NSUserDefaults resetStandardUserDefaults]non lo fa è oltre me.
jakeboxer,

2
@jboxer Ho appena trascorso un po 'di tempo a studiare la documentazione Apple e resetStandardUserDefaults fondamentalmente scarica il buffer in memoria sul disco e lo pulisce. Quindi la prossima volta che provi a recuperare un valore, deve catturarlo dal disco. Anche NSManagedObjectContext di Core Data utilizza una terminologia "reset" simile.
Christopher Rogers,

2
Oops, intendevo che cancella il buffer in memoria senza scriverlo sul disco. Pertanto, tutte le modifiche apportate prima della sincronizzazione su disco andranno perse.
Christopher Rogers,

4
Christopher, penso che tu l'abbia indietro anche se forse le cose sono cambiate. resetStandardUserDefaults è la chiamata più confusa che ho visto finora in iOS. I documenti di Apple dicono "Sincronizza tutte le modifiche apportate all'oggetto predefinito dell'utente condiviso e lo rilascia dalla memoria". quindi dovrebbe davvero essere chiamato flushAndReleaseStandardUserDefaults. Mi sto prendendo il tempo per commentare un vecchio commento perché sono stato appena preso da questa chiamata e voglio evitare che qualcun altro venga bruciato (ora devo dire a un client che devo aggiornare 90 app).
Andy Dent,

97

Hai provato a usare - removeObjectForKey?

 [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"defunctPreference"];

Saluti sbooth. Molto apprezzato.
TonyNeallon,

5
Un modo per rimuovere l'oggetto per tutte le chiavi esistenti?
samvermette,

2
Mentre capisco che questo sembra funzionare, perché defunctPreference non è una sorta di costante definita dal sistema? Sarei sicuramente nervoso che smetterebbe di funzionare un giorno in futuro.
David H,

Devi sincronizzare dopo?
Travis M.,

30

Ecco la risposta in Swift:

let appDomain = NSBundle.mainBundle().bundleIdentifier!
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(appDomain)

8
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(NSBundle.mainBundle().bundleIdentifier!)one-liner
Grace Shao,

3
O più sicuro:if let domainName = NSBundle.mainBundle().bundleIdentifier { NSUserDefaults.standardUserDefaults().removePersistentDomainForName(domainName) }
Valentin Shergin,

1
Swift 4 versione di Grace's oneliner:UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)
Carsten Hagemann,

28

Se ne hai bisogno durante lo sviluppo, puoi anche ripristinare il simulatore, eliminando tutto NSUserDefaults.

Simulatore iOS -> Ripristina contenuto e impostazioni ...

Tieni presente che eliminerà anche tutte le app e i file sul simulatore.


15
NSDictionary *defaultsDictionary = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
for (NSString *key in [defaultsDictionary allKeys]) {
                    [[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
}

7

In Swift:

let defaults = NSUserDefaults.standardUserDefaults()
defaults.dictionaryRepresentation().keys.forEach { defaults.removeObjectForKey($0) }

6

Nota: questa risposta è stata aggiornata anche per Swift.

Che ne dici di averlo su una linea?

Estendere la risposta di @Christopher Rogers - quella accettata.

[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];

e sì, a volte potresti averne bisogno synchronize,

[[NSUserDefaults standardUserDefaults] synchronize];

Ho creato un metodo per farlo,

- (void) clearDefaults {
    [[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

Veloce ?

Con swift è ancora più facile.

extension UserDefaults {
    class func clean() {
        guard let aValidIdentifier = Bundle.main.bundleIdentifier else { return }
        standard.removePersistentDomain(forName: aValidIdentifier)
        standard.synchronize()
    }
}

E utilizzo :

UserDefaults.clean()

6

Adoro le estensioni quando rendono il codice più pulito:

extension NSUserDefaults {
    func clear() {
        guard let domainName = NSBundle.mainBundle().bundleIdentifier else {
            return
        }

        self.removePersistentDomainForName(domainName)
    }
}

Swift 5

extension UserDefaults {
    func clear() {
        guard let domainName = Bundle.main.bundleIdentifier else {
            return
        }
        removePersistentDomain(forName: domainName)
        synchronize()
    }
}


2

Tutte le risposte di cui sopra sono molto pertinenti, ma se qualcuno non è ancora in grado di ripristinare le impostazioni predefinite dell'utente per l'app eliminata, è possibile ripristinare le impostazioni del contenuto del simulatore e funzionerà.inserisci qui la descrizione dell'immagine


2

È un bug o altro ma removePersistentDomainForNamenon funziona mentre cancella tutti i NSUserDefaultsvalori.

Quindi, l'opzione migliore è quella di ripristinare il PersistentDomaine che puoi fare nel modo seguente:

NSUserDefaults.standardUserDefaults().setPersistentDomain(["":""], forName: NSBundle.mainBundle().bundleIdentifier!)

1

Espandendo la risposta di @ folse ... Credo che un'implementazione più corretta sarebbe ...

NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
NSDictionary *defaultsDictionary = [[NSUserDefaults standardUserDefaults] persistentDomainForName: appDomain];
    for (NSString *key in [defaultsDictionary allKeys]) {
      NSLog(@"removing user pref for %@", key);
      [[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
    }

... chiamando persistentDomainForName di NSUserDefault: metodo. Come indicato dai documenti, il metodo "Restituisce un dizionario contenente le chiavi e i valori nel dominio persistente specificato." Chiamare dizionario Rappresentazione: restituirà invece un dizionario che probabilmente includerà altre impostazioni in quanto si applica a un ambito più ampio.

Se è necessario filtrare uno qualsiasi dei valori che devono essere ripristinati, è possibile eseguire l'iterazione sulle chiavi. Ovviamente, se vuoi semplicemente cancellare tutte le preferenze per l'app senza riguardo, allora uno degli altri metodi pubblicati sopra è il più efficiente.



0

Prova questo, funziona per me.

Singola riga di codice

[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.