NSUserDefaults removeObjectForKey vs. setObject: nil

116

Sind die folgenden zwei Zeilen gleichwertig?

1. [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"example key"]

2. [[NSUserDefaults standardUserDefaults] setObject:nil forKey:@"example key"]

ma11hew28
quelle
1
Ja, außer der erste macht Ihre Absicht viel klarer.
BallpointBen

Antworten:

14

Swift 3.0

Die folgende Antwort ist nicht mehr der Fall, als ich dies getestet habe. Wenn nildas Ergebnis festgelegt ist, werden NSCFData gespeichert. Möglicherweise eine NSNull-Objektreferenz, aber ich bin nicht positiv.

Um einen Wert für einen Schlüssel vollständig zu entfernen, verwenden Sie UserDefaults.standard.removeObject(forKey: "YourDefault")

Ich habe mit folgendem Code getestet:

UserDefaults.standard.set(["a", "b", "c"], forKey: "MyDefaults")
print("Test A: My saved defaults \(UserDefaults.standard.object(forKey: "MyDefaults"))")

UserDefaults.standard.set(nil, forKey: "MyDefaults")
print("Test B: My defaults set to nil \(UserDefaults.standard.object(forKey: "MyDefaults"))")

UserDefaults.standard.removeObject(forKey: "MyDefaults")
print("Test C: My defaults removed \(UserDefaults.standard.object(forKey: "MyDefaults"))")
Sean
quelle
Interessant ist, dass ich in Swift, wenn ich set (nil, forKey: ...) eingebe und "Zur Definition springen" verwende, zum URL-Setter komme. Der Kommentar für diese Funktion lautet "-setURL: forKey entspricht -setObject: forKey: außer dass der Wert in NSData archiviert wird." Dies könnte erklären, warum es sich schlecht verhält - da es zwei überladene Funktionen gibt, die Null akzeptieren, muss Swift eine auswählen, aber setURL verhält sich nicht gleich.
Richard Venable
96

Ja, beide Codezeilen sind äquivalent. Beide führen zu einem Null-Lesevorgang

id obj = [[NSUserDefaults standardUserDefaults] objectForKey:@"example key"];

NSUserDefaultsgibt nil zurück, wenn der Schlüssel nicht gefunden wurde. Ich würde empfehlen, die zu verwendenremoveObjectForKey anstatt es auf Null zu setzen.

Hier erfahren Sie, wie Sie testen, ob durch Setzen des Schlüsselwerts auf Null der Schlüsseleintrag entfernt wurde NSUserDefaults standardUserDefaults.

NSArray *keys = [[[NSUserDefaults standardUserDefaults] dictionaryRepresentation] allKeys] copy];
   for(NSString *key in keys) {
       NSLog(@"Key Name: %@", key);
}
[keys release];

oder geben Sie einfach das Schlüssel- / Wertwörterbuch von aus NSUserDefaults standardUserDefaults

NSLog(@"All contents of NSUserDefaults: %@", [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]);
Raketenmann
quelle
Ja, aber wenn Sie es auf Null setzen, wird es automatisch removeObjectForKey?
ma11hew28
Ich bin mir nicht sicher, ob durch Setzen von 'nil' der Schlüsseleintrag in den [NSUserDefaults standardUserDefaults] entfernt wird. Ein schneller Test wäre, 'allKeys' [[NSUserDefaults standardUserDefaults] allKeys] abzurufen und die NSArrya der Schlüsselnamen zu durchlaufen, um herauszufinden, ob das Setzen eines Schlüssels auf nil den Schlüssel aus dem 'allKey'-Array entfernt.
RocketMan
9
Das Ergebnis ist 'YES'. Sowohl 'removeObjectForKey' als auch 'setObject: nil' entfernen den Schlüssel @ "Beispielschlüssel" aus [NSUserDefaults standardUserDefaults]
RocketMan
9
Vielen Dank! Das habe ich auch bestätigt. Nur zur Verdeutlichung setObject:nilwird auch das Objekt entfernt, nicht nur sein Schlüssel. Beide Funktionen bewirken also genau das gleiche Ergebnis. Wenn Sie das einzige gespeicherte Objekt (und den Schlüssel) entfernen (oder auf Null setzen), wird die gesamte .plist-Datei gelöscht.
ma11hew28
1

Swift 5.0 + iOS 11 und höher

Beide Methoden entfernen den Wert. Versuchte dies auf einem Spielplatz:

import Foundation

let key = "Test"
let value = "test"
let defaults = UserDefaults.standard

func printUD() {
    print("UserDefaults after modification:\n")
    defaults.dictionaryRepresentation().forEach { print("\($0): \($1)\n") }
    print("-------------\n\n")
}

defaults.set(value, forKey: key); printUD()
defaults.set(nil, forKey: key); printUD()
defaults.set(value, forKey: key); printUD()
defaults.removeObject(forKey: key); printUD()

Vor iOS 11 dies führt in der Serialisierung nilin Dataund wirft einen Fehler.

Daniil Korotin
quelle