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.