NSUserDefaults removeObjectForKey vs setObject: nil


116

Les deux lignes suivantes sont-elles équivalentes?

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

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


1
Oui, sauf que le premier rend votre intention beaucoup plus claire.
BallpointBen

Réponses:


14

Swift 3.0

La réponse ci-dessous n'est plus le cas lorsque j'ai testé cela. Lorsqu'il est défini sur nille résultat, NSCFData est stocké. Peut-être une référence d'objet NSNull, mais je ne suis pas positif.

Pour supprimer complètement une valeur pour une utilisation de clé UserDefaults.standard.removeObject(forKey: "YourDefault")

J'ai testé avec le code suivant:

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"))")

Intéressant, dans Swift, quand je tape set (nil, forKey: ...), et que j'utilise "jump to definition", cela m'amène au setter d'URL. Le commentaire de cette fonction dit "-setURL: forKey équivaut à -setObject: forKey: sauf que la valeur est archivée dans NSData." Cela pourrait expliquer pourquoi il se comporte mal - comme il y a deux fonctions surchargées qui acceptent nil, Swift doit en choisir une, mais setURL ne se comporte pas de la même manière.
Richard Venable

96

Oui, les deux lignes de code sont équivalentes, les deux entraîneront une lecture nulle

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

NSUserDefaultsretournera nil si la clé n'a pas été trouvée. Je recommanderais d'utiliser le removeObjectForKeyau lieu de le définir sur nil.

voici comment tester si la définition de la valeur de clé sur nil a supprimé l'entrée de clé de NSUserDefaults standardUserDefaults.

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

ou simplement vider le dictionnaire clé / valeur de NSUserDefaults standardUserDefaults

NSLog(@"All contents of NSUserDefaults: %@", [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]);

Oui, mais si vous le définissez sur zéro, le fait-il automatiquement removeObjectForKey?
ma11hew28

Je ne sais pas si le paramétrer sur «nil» supprimera l'entrée de clé dans [NSUserDefaults standardUserDefaults]. Un test rapide serait d'obtenir 'allKeys' [[NSUserDefaults standardUserDefaults] allKeys] et de parcourir la NSArrya des noms de clés, découvrez si la définition d'une clé à nil supprime la clé du tableau 'allKey'.
RocketMan

9
le résultat est 'OUI' à la fois 'removeObjectForKey' et 'setObject: nil' supprimera la clé @ "example key" de [NSUserDefaults standardUserDefaults]
RocketMan

9
Merci! J'ai également confirmé cela. Juste pour clarifier, setObject:nilsupprimera également l'objet, pas seulement sa clé. Ainsi, les deux fonctions produisent exactement le même résultat. De plus, si vous supprimez (ou définissez sur nil) le seul objet (et clé) stocké, tout le fichier .plist est supprimé.
ma11hew28

1

Swift 5.0 + iOS 11 et plus

Les deux méthodes suppriment la valeur. J'ai essayé cela dans une aire de jeux:

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()

Avant iOS 11 cela se traduira par de sérialisation nildans Dataet une erreur.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.