Xóa NSUserDefaults


Câu trả lời:


514

Bạn có thể xóa tên miền liên tục của ứng dụng như thế này:

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

Trong Swift 3 trở lên:

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

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


Đ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 tự động phát hành vì nó không bắt đầu bằng init hoặc mới, vì vậy bạn sẽ phát hành quá mức.
Christopher Rogers

1
Mừng cho 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

2
@IcyBlueRose Đối tượng được trả về bởi bundleIdentifier giống như đối tượng được tham chiếu bởi appDomain.
Christopher Rogers

2
Tôi dường như không thể làm cho nó hoạt động vào ngày 10.8 nữa, ai đó có thể vui lòng xác nhận rằng nó hoạt động không? Đây là một câu hỏi SO có liên quan: stackoverflow.com/questions/13595415/ từ
DaGaMs

102

Mã này đặt lại mặc định cho miền đăng ký:

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

Nói cách khác, nó removeObjectForKeycho mọi khóa duy nhất bạn từng đăng ký trong ứng dụng đó.

Tín dụng cho Ken Thomases trên chủ đề Diễn đàn nhà phát triển Apple này .


4
Cảm ơn nhiều. Tại sao [NSUserDefaults resetStandardUserDefaults]không làm điều này là ngoài tôi.
jakeboxer

2
@jboxer Tôi vừa dành một chút thời gian để nghiên cứu tài liệu của Apple và resetSt ChuẩnUserDefaults về cơ bản sẽ xóa bộ đệm trong bộ nhớ vào đĩa và xóa sạch nó. Vì vậy, lần tới 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ữ "đặt lại" tương tự.
Christopher Rogers

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

4
Christopher, tôi nghĩ bạn có nó ngược mặc dù có thể mọi thứ đã thay đổi. resetSt ChuẩnUserDefaults là cuộc gọi có tên khó hiểu nhất tôi từng thấy cho đến nay trong iOS. Tài liệu Apple cho biết "Đồng bộ hóa mọi thay đổi được thực hiện đối với người dùng được chia sẻ mặc định và giải phóng nó khỏi bộ nhớ." vì vậy nó thực sự nên được gọi là flushAndReleaseSt ChuẩnUserDefaults. Tôi đang dành thời gian để bình luận về một bình luận cũ vì tôi vừa bị cuộc gọi này bắt gặp và muốn tránh bất kỳ ai khác bị đốt cháy (bây giờ tôi phải nói với một khách hàng tôi cần cập nhật 90 ứng dụng).
Andy Dent

97

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

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

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

5
Bất kỳ cách nào để loại bỏ đố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à defposedPreference một số loại hệ thống được xác định không đổi? 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.
David H

Bạn có phải đồng bộ hóa sau?
Travis M.

30

Đây là câu trả lời trong Swift:

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

8
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(NSBundle.mainBundle().bundleIdentifier!)một lớp lót
Grace Shao

3
Hoặc an toàn hơn:if let domainName = NSBundle.mainBundle().bundleIdentifier { NSUserDefaults.standardUserDefaults().removePersistentDomainForName(domainName) }
Valentin Shergin

1
Swift 4 phiên bản oneliner của Grace:UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)
Carsten Hagemann

28

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

Trình mô phỏng iOS -> Đặt lại nội dung và cài đặt ...

Hãy nhớ rằng nó cũng sẽ xóa tất cả các ứng dụng và tệp trên trình giả lập.


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

7

Trong Swift:

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

6

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

Điều gì về để có nó trên một dòng?

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

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

và vâng, đôi khi bạn có thể cần synchronizenó,

[[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 ?

Với swift thậm chí còn dễ dàng hơn.

extension UserDefaults {
    class func clean() {
        guard let aValidIdentifier = Bundle.main.bundleIdentifier else { return }
        standard.removePersistentDomain(forName: aValidIdentifier)
        standard.synchronize()
    }
}

Và cách sử dụng :

UserDefaults.clean()

6

Tôi thích các tiện ích mở rộng khi chúng làm cho mã sạch hơn:

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

        self.removePersistentDomainForName(domainName)
    }
}

Swift 5

extension UserDefaults {
    func clear() {
        guard let domainName = Bundle.main.bundleIdentifier else {
            return
        }
        removePersistentDomain(forName: domainName)
        synchronize()
    }
}


2

Tất cả các câu trả lời ở trên đều rất phù hợp, nhưng nếu ai đó vẫn không thể đặt lại xác nhận người dùng cho ứng dụng đã xóa, thì bạn có thể đặt lại cài đặt nội dung của trình giả lập và nó sẽ hoạt động.nhập mô tả hình ảnh ở đây


2

Đó là một lỗi hoặc bất cứ điều gì nhưng removePersistentDomainForNamenó không hoạt động trong khi xóa tất cả các NSUserDefaultsgiá trị.

Vì vậy, tùy chọn tốt hơn là đặt lại PersistentDomainvà bạn có thể thực hiện thông qua cách sau:

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

1

Mở rộng câu trả lời của @ folse ... Tôi tin rằng một triển khai đúng đắn 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];
    }

... đang gọi phương thức continentDomainForName: của NSUserDefault. Là 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." Gọi từ điển Xuất hiện: thay vào đó, sẽ trả về một từ điển có thể sẽ bao gồm các cài đặt khác khi 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 sẽ được đặt lại, thì lặp lại các phím là cách để thực hiện. Rõ ràng, nếu bạn muốn chỉ cần nuke tất cả các prefs cho ứng dụng mà không quan tâm, thì một trong những phương pháp khác được đăng ở trên là hiệu quả nhất.


0

nếu cài đặt ứng dụng cần thiết lập lại là nsuserdefault để truy cập micrô (trường hợp của tôi), một giải pháp đơn giản là câu trả lời từ Anthony McCormick ( Iphone - Làm cách nào để cho phép ứng dụng truy cập vào phương tiện trên thiết bị? - ALAssetsL LibraryErrorDomain Code = -3312 "Truy cập bị từ chối toàn cầu" ).

trên thiết bị, đi tới Cài đặt> Chung> Đặt lại> Đặt lại Cảnh báo vị trí


0

Hãy thử cái này, nó làm việc cho tôi.

Một dòng mã

[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
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.