NSUserDefaults löschen


Antworten:


514

Sie können die persistente Domäne der Anwendung folgendermaßen entfernen:

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

In Swift 3 und höher:

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

Dies ähnelt der Antwort von @samvermette, ist aber IMO ein bisschen sauberer.


Das hat super geklappt, danke! Vergessen Sie nicht, appDomain danach freizugeben.
IcyBlueRose

15
@IcyBlueRose - bundleIdentifier ist ein automatisch freigegebenes Objekt, da es nicht mit init oder new beginnt, sodass Sie es übermäßig freigeben würden.
Christopher Rogers

1
Gut zu wissen, danke! Aber ich habe über die String-AppDomain gesprochen. Wird das auch automatisch veröffentlicht?
IcyBlueRose

2
@IcyBlueRose Das von bundleIdentifier zurückgegebene Objekt entspricht dem Objekt, auf das von appDomain verwiesen wird.
Christopher Rogers

2
Ich kann nicht mehr scheinen, dass dies auf 10.8 funktioniert. Könnte jemand bitte bestätigen, dass dies funktioniert? Hier ist eine verwandte SO-Frage: stackoverflow.com/questions/13595415/…
DaGaMs

102

Dieser Code setzt die Standardeinstellungen auf die Registrierungsdomäne zurück:

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

Mit anderen Worten, es removeObjectForKey für jeden einzelnen Schlüssel, den Sie jemals in dieser App registriert haben.

Dank an Ken Thomases in diesem Thread des Apple Developer Forums .


4
Vielen Dank. Warum [NSUserDefaults resetStandardUserDefaults]das nicht so ist, ist mir ein Rätsel.
Jakeboxer

2
@jboxer Ich habe gerade einige Zeit damit verbracht, die Apple-Dokumentation zu studieren und resetStandardUserDefaults löscht den In-Memory-Puffer im Grunde genommen auf die Festplatte und löscht ihn sauber. Wenn Sie also das nächste Mal versuchen, einen Wert abzurufen, muss dieser von der Festplatte abgerufen werden. Der NSManagedObjectContext von Core Data verwendet ebenfalls eine ähnliche "Reset" -Terminologie.
Christopher Rogers

2
Hoppla, ich meinte, dass es den In-Memory-Puffer löscht, ohne ihn auf die Festplatte zu schreiben. Alle Änderungen, die Sie vor der Synchronisierung mit der Festplatte vorgenommen haben, gehen verloren.
Christopher Rogers

4
Christopher, ich denke du hast es rückwärts, obwohl sich vielleicht die Dinge geändert haben. resetStandardUserDefaults ist der verwirrendste Aufruf, den ich bisher in iOS gesehen habe. In den Apple Docs heißt es: "Synchronisiert alle Änderungen, die am Standardobjekt des freigegebenen Benutzers vorgenommen wurden, und gibt es aus dem Speicher frei." Daher sollte es wirklich flushAndReleaseStandardUserDefaults heißen. Ich nehme mir die Zeit, um einen alten Kommentar zu kommentieren, weil ich gerade von diesem Anruf erwischt wurde und verhindern möchte, dass andere verbrannt werden (ich muss jetzt einem Client mitteilen, dass ich 90 Apps aktualisieren muss).
Andy Dent

97

Haben Sie versucht, - zu verwenden removeObjectForKey?

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

Prost sbooth. Sehr geschätzt.
TonyNeallon

5
Gibt es eine Möglichkeit, Objekte für alle vorhandenen Schlüssel zu entfernen?
Samvermette

2
Obwohl ich verstehe, dass dies zu funktionieren scheint, warum ist defunctPreference nicht eine Art systemdefinierte Konstante? Ich wäre sicher nervös, dass es eines Tages aufhören würde zu arbeiten.
David H

Müssen Sie danach synchronisieren?
Travis M.

30

Hier ist die Antwort in Swift:

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

8
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(NSBundle.mainBundle().bundleIdentifier!)Einzeiler
Grace Shao

3
Oder sicherer:if let domainName = NSBundle.mainBundle().bundleIdentifier { NSUserDefaults.standardUserDefaults().removePersistentDomainForName(domainName) }
Valentin Shergin

1
Swift 4 Version von Grace Oneliner:UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)
Carsten Hagemann

28

Wenn Sie es während der Entwicklung benötigen, können Sie auch Ihren Simulator zurücksetzen und alle löschen NSUserDefaults.

iOS Simulator -> Inhalt und Einstellungen zurücksetzen ...

Beachten Sie, dass auch alle Apps und Dateien im Simulator gelöscht werden.


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

Hinweis: Diese Antwort wurde auch für Swift aktualisiert.

Was ist mit einer Zeile?

Erweitern der Antwort von @Christopher Rogers - die akzeptierte.

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

und ja, irgendwann müssen Sie es vielleicht brauchen synchronize,

[[NSUserDefaults standardUserDefaults] synchronize];

Ich habe eine Methode dafür erstellt,

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

Schnell ?

Mit Swift ist es noch einfacher.

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

Und Verwendung :

UserDefaults.clean()

6

Ich liebe Erweiterungen, wenn sie den Code sauberer machen:

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

Alle oben genannten Antworten sind sehr relevant. Wenn jedoch jemand die Benutzerstandards für die gelöschte App immer noch nicht zurücksetzen kann, können Sie die Inhaltseinstellungen Ihres Simulators zurücksetzen, und es funktioniert.Geben Sie hier die Bildbeschreibung ein


2

Es ist ein Fehler oder was auch immer, aber das removePersistentDomainForNamefunktioniert nicht, während alle NSUserDefaultsWerte gelöscht werden.

Die bessere Option ist also, das zurückzusetzen PersistentDomainund dies auf folgende Weise zu tun:

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

1

Die Antwort von @ folse erweitern ... Ich glaube, eine korrektere Implementierung wäre ...

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];
    }

... Aufruf der persistentDomainForName: -Methode von NSUserDefault. Wie in den Dokumenten angegeben, gibt die Methode "Ein Wörterbuch zurück, das die Schlüssel und Werte in der angegebenen persistenten Domäne enthält". Wenn Sie dictionaryRepresentation aufrufen, wird stattdessen ein Wörterbuch zurückgegeben, das wahrscheinlich andere Einstellungen enthält, da es für einen größeren Bereich gilt.

Wenn Sie einen der zurückzusetzenden Werte herausfiltern müssen, können Sie dies über die Schlüssel wiederholen. Wenn Sie einfach alle Einstellungen für die App ohne Rücksicht auf Nuklearwaffen ändern möchten, ist eine der anderen oben beschriebenen Methoden die effizienteste.



0

Versuchen Sie dies, es funktioniert für mich.

Einzelne Codezeile

[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.