NSUserDefaults removeObjectForKey vs. setObject: nil

116

Apakah kedua baris berikut ini setara?

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

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

ma11hew28
sumber
1
Ya, kecuali yang pertama membuat niat Anda jauh lebih jelas.
BallpointBen

Jawaban:

14

Swift 3.0.0

Jawaban di bawah ini tidak lagi menjadi masalah ketika saya menguji ini. Ketika diatur ke nilhasilnya adalah NSCFData disimpan. Mungkin referensi objek NSNull, tapi saya tidak yakin.

Untuk sepenuhnya menghapus nilai penggunaan kunci UserDefaults.standard.removeObject(forKey: "YourDefault")

Saya menguji dengan kode berikut:

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
sumber
Menarik, di Swift, saat saya mengetik set (nil, forKey: ...), dan menggunakan "jump to definition", saya dibawa ke penyetel URL. Komentar untuk fungsi itu mengatakan "-setURL: forKey sama dengan -setObject: forKey: kecuali bahwa nilainya diarsipkan ke NSData." Ini bisa menjelaskan mengapa ini berperilaku tidak semestinya - karena ada dua fungsi berlebih yang menerima nil, Swift harus memilih satu, tetapi setURL tidak berperilaku sama.
Richard Venable
96

Ya, kedua baris kode itu setara, keduanya akan menghasilkan pembacaan nihil

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

NSUserDefaultsakan mengembalikan nol jika kunci tidak ditemukan. Saya akan merekomendasikan untuk menggunakanremoveObjectForKey alih alih menyetelnya ke nol.

berikut adalah cara menguji apakah menyetel nilai kunci ke nil menghapus entri kunci dari NSUserDefaults standardUserDefaults.

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

atau cukup buang kamus kunci / nilai NSUserDefaults standardUserDefaults

NSLog(@"All contents of NSUserDefaults: %@", [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]);
Manusia Roket
sumber
Ya, tetapi jika Anda menyetelnya ke nihil, apakah secara otomatis removeObjectForKey?
ma11hew28
tidak yakin apakah menyetelnya ke 'nil' akan menghapus entri kunci di [NSUserDefaults standardUserDefaults]. Tes cepatnya adalah mendapatkan 'allKeys' [[NSUserDefaults standardUserDefaults] allKeys] dan mengulang melalui NSArrya nama kunci, mencari tahu apakah menyetel kunci ke nil menghapus kunci dari larik 'allKey'.
RocketMan
9
hasilnya adalah 'YES' baik 'removeObjectForKey' dan 'setObject: nil' akan menghapus key @ "example key" dari [NSUserDefaults standardUserDefaults]
RocketMan
9
Terima kasih! Saya mengkonfirmasi ini juga. Hanya untuk memperjelas, setObject:niljuga akan menghapus objek, bukan hanya kuncinya. Jadi, kedua fungsi tersebut menyebabkan hasil yang persis sama. Selain itu, jika Anda menghapus (atau mengatur ke nihil) satu-satunya objek yang disimpan (dan kunci), seluruh file .plist akan dihapus.
ma11hew28
1

Swift 5.0 + iOS 11 dan yang lebih baru

Kedua metode tersebut menghapus nilainya. Mencoba ini di taman bermain:

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

Sebelum iOS 11, ini akan mengakibatkan serialisasi nilmenjadi Datadan menimbulkan kesalahan.

Daniil Korotin
sumber