2009-02-13 27 views
270

Tôi đang sử dụng +[NSUserDefaults standardUserDefaults] để lưu cài đặt ứng dụng. Điều này bao gồm khoảng một chục giá trị chuỗi. Có thể xóa vĩnh viễn các giá trị này thay vì chỉ đặt chúng thành giá trị mặc định không?Xóa NSUserDefaults

+1

[** Xóa tất cả các phím từ một NSUserDefaults **] (http://stackoverflow.com/questions/6797096/delete-all-keys-from-a-nsuserdefaults -dictionary-iphone) – Hemang

Trả lời

486

Bạn có thể loại bỏ miền dai dẳng của ứng dụng như thế này:

NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier]; 
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain]; 

Trong Swift 3 và sau:

if let bundleID = Bundle.main.bundleIdentifier { 
    UserDefaults.standard.removePersistentDomain(forName: bundleID) 
} 

Đây là tương tự như câu trả lời của @samvermette nhưng là một chút IMO sạch hơn.

+0

Điều này làm việc tuyệt vời, cảm ơn! Chỉ cần đừng quên phát hành appDomain sau đó. – IcyBlueRose

+15

@IcyBlueRose - bundleIdentifier là một đối tượng autoreleased vì nó không bắt đầu bằng init hoặc mới, vì vậy bạn sẽ phát hành nó quá mức. –

+1

Điều cần biết, cảm ơn bạn! Nhưng tôi đã nói về chuỗi appDomain. Đó là tự động phát hành cũng? – IcyBlueRose

94

Bạn đã thử sử dụng - removeObjectForKey?

[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"defunctPreference"]; 
+0

Chúc mừng sbooth. Nhiều đánh giá cao. – TonyNeallon

+5

Bất kỳ cách nào để xóa đối tượng cho tất cả các khóa hiện có? – samvermette

+2

Trong khi tôi hiểu điều này dường như hoạt động, tại sao không phải là defunctPreference một số loại hệ thống được xác định liên tục? Tôi chắc chắn sẽ lo lắng nó sẽ ngừng hoạt động vào một ngày nào đó trong tương lai. –

101

Mã này reset giá trị mặc định cho miền đăng ký:

[[NSUserDefaults standardUserDefaults] setPersistentDomain:[NSDictionary dictionary] forName:[[NSBundle mainBundle] bundleIdentifier]]; 

Nói cách khác, nó removeObjectForKey cho mỗi phím duy nhất bạn đã bao giờ đăng ký trong ứng dụng đó.

Tín dụng cho Ken Thomases về vấn đề này của Apple diễn Developer thread.

+4

Cảm ơn một nhóm. Tại sao '[NSUserDefaults resetStandardUserDefaults]' không làm điều này là ngoài tôi. – jakeboxer

+2

@jboxer Tôi chỉ dành một chút thời gian nghiên cứu tài liệu của Apple và resetStandardUserDefaults về cơ bản xóa bộ đệm trong bộ nhớ ra đĩa và lau sạch nó. Vì vậy, lần sau khi bạn cố gắng lấy một giá trị nó phải lấy nó từ đĩa. NSManagedObjectContext của Core Data cũng sử dụng thuật ngữ "reset" tương tự. –

+2

Rất tiếc, tôi có nghĩa là nó xóa bộ đệm trong bộ nhớ mà không cần ghi nó vào đĩa. Vì vậy, bất kỳ thay đổi nào bạn đã thực hiện trước khi đồng bộ hóa vào đĩa sẽ bị mất. –

27

Nếu bạn cần trong khi phát triển, bạn cũng có thể đặt lại trình mô phỏng, xóa tất cả NSUserDefaults.

iOS Simulator -> Reset Content and Settings ...

Gấu nhớ rằng nó cũng sẽ xóa tất cả các ứng dụng và tập tin trên mô phỏng.

13
NSDictionary *defaultsDictionary = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]; 
for (NSString *key in [defaultsDictionary allKeys]) { 
        [[NSUserDefaults standardUserDefaults] removeObjectForKey:key]; 
} 
1

Mở rộng về câu trả lời @ folse của ... Tôi tin rằng việc thực hiện chính xác hơn sẽ là ...

NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier]; 
NSDictionary *defaultsDictionary = [[NSUserDefaults standardUserDefaults] persistentDomainForName: appDomain]; 
    for (NSString *key in [defaultsDictionary allKeys]) { 
     NSLog(@"removing user pref for %@", key); 
     [[NSUserDefaults standardUserDefaults] removeObjectForKey:key]; 
    } 

... gọi persistentDomainForName NSUserDefault của: Phương pháp. Theo trạng thái tài liệu, phương thức "Trả về một từ điển chứa các khóa và giá trị trong miền liên tục được chỉ định". Thay vào đó, gọi từ điểnĐại diện: sẽ trả lại một từ điển có khả năng sẽ bao gồm các cài đặt khác vì nó áp dụng cho phạm vi rộng hơn.

Nếu bạn cần lọc ra bất kỳ giá trị nào cần đặt lại, thì lặp lại qua các phím là cách để thực hiện. Rõ ràng, nếu bạn muốn chỉ nuke tất cả các prefs cho các ứng dụng mà không quan tâm, sau đó một trong những phương pháp khác được đăng ở trên là hiệu quả nhất.

1

Tất cả các câu trả lời ở trên là rất phù hợp, nhưng nếu ai đó vẫn không thể thiết lập lại các userdefaults cho ứng dụng đã xóa, sau đó bạn có thể thiết lập lại các thiết lập nội dung của bạn giả lập, và nó sẽ làm việc.enter image description here

29

Dưới đây là câu trả lời trong Swift:

let appDomain = NSBundle.mainBundle().bundleIdentifier! 
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(appDomain) 
+7

'NSUserDefaults.standardUserDefaults(). RemovePersistentDomainForName (NSBundle.mainBundle(). BundleIdentifier!) 'one-liner –

+2

Hoặc an toàn hơn:' nếu cho domainName = NSBundle.mainBundle(). bundleIdentifier {NSUserDefaults.standardUserDefaults(). removePersistentDomainForName (domainName)} ' –

3

Lưu ý: Câu trả lời này đã được cập nhật cho Swift quá.

Điều gì sắp có trên một dòng?

Mở rộng @Christopher Câu trả lời của Rogers - câu trả lời được chấp nhận.

[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]]; 

và có, đôi khi bạn có thể cần phải synchronize nó,

[[NSUserDefaults standardUserDefaults] synchronize]; 

tôi đã tạo ra một phương pháp để làm điều này,

- (void) clearDefaults { 
    [[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]]; 
    [[NSUserDefaults standardUserDefaults] synchronize]; 
} 

Swift?

Nhanh chóng thậm chí còn dễ dàng hơn.

extension UserDefaults { 
    class func clearDefaults() -> Bool { 
     guard let aValidIdentifier = Bundle.main.bundleIdentifier else { return false } 
     self.standard.removePersistentDomain(forName: aValidIdentifier) 
     self.standard.synchronize() 
     return true 
    } 
} 

Và sử dụng:

if UserDefaults.clearDefaults() { 
    //Done! 
} else { 
    //Not. 
} 
2

Đó là một lỗi hoặc bất cứ điều gì nhưng removePersistentDomainForName không được làm việc trong khi thanh toán bù trừ tất cả các NSUserDefaults giá trị.

Vì vậy, lựa chọn tốt hơn là để thiết lập lại các PersistentDomain và rằng bạn có thể làm thông qua cách sau:

NSUserDefaults.standardUserDefaults().setPersistentDomain(["":""], forName: NSBundle.mainBundle().bundleIdentifier!) 
5

Trong Swift:

let defaults = NSUserDefaults.standardUserDefaults() 
defaults.dictionaryRepresentation().keys.forEach { defaults.removeObjectForKey($0) } 
5

Tôi yêu phần mở rộng khi họ làm cho đoạn code sạch hơn:

extension NSUserDefaults { 
    func clear() { 
     guard let domainName = NSBundle.mainBundle().bundleIdentifier else { 
      return 
     } 

     self.removePersistentDomainForName(domainName) 
    } 
} 
0

Hãy thử tính năng này, nó phù hợp với tôi.

dòng Độc mã

[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]]; 
Các vấn đề liên quan