NSUserDefaults RemoveObjectForKey vs. setObject: nil


116

Чи еквівалентні наступні два рядки?

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

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


1
Так, за винятком першого, ваш намір значно зрозуміліший.
BallpointBen

Відповіді:


14

Swift 3.0

Наведена нижче відповідь більше не стосується, коли я це перевіряв. Якщо встановлено nilрезультат, NSCFData зберігається. Можливо, посилання на об’єкт NSNull, але я не позитивний.

Повністю видалити значення для ключового використання UserDefaults.standard.removeObject(forKey: "YourDefault")

Я перевірив наступний код:

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

Цікаво, що в Swift, коли я набираю set (nil, forKey: ...) і використовую "перейти до визначення", це приводить мене до встановлення URL-адрес. У коментарі до цієї функції написано "-setURL: forKey еквівалентно -setObject: forKey: за винятком того, що значення архівується в NSData." Це може пояснити, чому це погано поводиться - оскільки є дві перевантажені функції, які приймають нуль, Swift повинен вибрати одну, але setURL не поводиться однаково.
Річард Венебл

96

Так, обидва рядки коду рівноцінні, обидва призведе до нульового зчитування

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

NSUserDefaultsповерне нуль, якщо ключ не знайдено. Я рекомендував би скористатисяremoveObjectForKey замість щоб встановити його на нуль.

Ось як перевірити, чи не встановив значення ключа для нуля, видалено ключ NSUserDefaults standardUserDefaults.

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

або просто скинути ключ / словник словника NSUserDefaults standardUserDefaults

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

Так, але якщо ви встановите його на нуль, чи стане це автоматично removeObjectForKey?
ma11hew28

не впевнений, що якщо встановити його на "нуль", буде видалено запис ключа в [NSUserDefaults standardUserDefaults]. Швидкий тест полягатиме в тому, щоб отримати 'allKeys' [[NSUserDefaults standardUserDefaults] allKeys] і повторити через NSArrya ключові імена, з’ясувати, чи встановлення ключа для нуля видаляє ключ з масиву 'allKey'.
RocketMan

9
результат - "ТАК", і "removeObjectForKey", і "setObject: nil" видалять ключ @ "приклад ключ" з [NSUserDefaults standardUserDefaults]
RocketMan

9
Дякую! Я це також підтвердив. Тільки для уточнення setObject:nilтакож видалить об’єкт, а не лише його ключ. Отже, обидві функції викликають абсолютно однаковий результат. Крім того, якщо ви видалите (або встановите на нуль) єдиний збережений об'єкт (і ключ), весь файл .plist буде видалений.
ma11hew28

1

Swift 5.0 + iOS 11 і новіших версій

Обидва способи видаляють значення. Спробував це на дитячому майданчику:

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

Перед прошивкою 11 це призведе в сериализации nilв Dataі видасть помилку.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.