NSUserDefaults removeObjectForKey so với setObject: nil


116

Hai dòng sau có tương đương không?

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

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


1
Có, ngoại trừ điều đầu tiên làm cho ý định của bạn rõ ràng hơn nhiều.
BallpointBen

Câu trả lời:


14

Swift 3.0

Câu trả lời dưới đây không còn là trường hợp khi tôi kiểm tra điều này. Khi được đặt thành nilkết quả là NSCFData được lưu trữ. Có thể là một tham chiếu đối tượng NSNull, nhưng tôi không khẳng định.

Để xóa hoàn toàn một giá trị cho việc sử dụng khóa UserDefaults.standard.removeObject(forKey: "YourDefault")

Tôi đã thử nghiệm với mã sau:

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

Thật thú vị, trong Swift, khi tôi nhập set (nil, forKey: ...) và sử dụng "nhảy đến định nghĩa", nó sẽ đưa tôi đến trình thiết lập URL. Nhận xét cho hàm đó cho biết "-setURL: forKey tương đương với -setObject: forKey: ngoại trừ giá trị được lưu trữ vào NSData." Điều này có thể giải thích tại sao nó hoạt động sai - vì có hai hàm quá tải chấp nhận nil, Swift phải chọn một hàm, nhưng setURL không hoạt động giống nhau.
Richard Venable

96

Có, cả hai dòng mã đều tương đương nhau, cả hai sẽ dẫn đến không đọc

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

NSUserDefaultssẽ trả về nil nếu không tìm thấy khóa. Tôi khuyên bạn nên sử dụng removeObjectForKeythay vì đặt nó thành nil.

đây là cách kiểm tra xem việc đặt giá trị khóa thành nil có xóa mục nhập khóa khỏi không NSUserDefaults standardUserDefaults.

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

hoặc đơn giản là kết xuất từ ​​điển khóa / giá trị của NSUserDefaults standardUserDefaults

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

Đúng, nhưng nếu bạn đặt nó thành nil, nó có tự động removeObjectForKeykhông?
ma11hew28

không chắc nếu đặt nó thành 'nil' sẽ xóa mục nhập khóa trong [NSUserDefaults standardUserDefaults]. Một bài kiểm tra nhanh sẽ là lấy 'allKeys' [[NSUserDefaults standardUserDefaults] allKeys] và lặp qua NSArrya của các tên khóa, tìm hiểu xem việc đặt khóa thành nil có xóa khóa khỏi mảng "allKey" hay không.
RocketMan

9
kết quả là 'CÓ' cả 'removeObjectForKey' và 'setObject: nil' sẽ xóa key @ "example key" khỏi [NSUserDefaults standardUserDefaults]
RocketMan

9
cảm ơn! Tôi cũng xác nhận điều này. Chỉ cần làm rõ, setObject:nilcũng sẽ loại bỏ đối tượng, không chỉ khóa của nó. Vì vậy, cả hai hàm đều gây ra cùng một kết quả. Ngoài ra, nếu bạn xóa (hoặc đặt thành nil) đối tượng được lưu trữ duy nhất (và khóa), toàn bộ tệp .plist sẽ bị xóa.
ma11hew28,

1

Swift 5.0 + iOS 11 trở lên

Cả hai phương pháp đều xóa giá trị. Đã thử điều này trong một sân chơi:

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

Trước iOS 11, điều này sẽ dẫn đến việc tuần tự hóa nilvào Datavà gây ra lỗi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.