Menghapus NSUserDefaults


Jawaban:


514

Anda dapat menghapus domain persisten aplikasi seperti ini:

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

Dalam Swift 3 dan yang lebih baru:

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

Ini mirip dengan jawaban oleh @samvermette tetapi sedikit lebih bersih IMO.


Ini berhasil, terima kasih! Jangan lupa untuk melepaskan appDomain sesudahnya.
IcyBlueRose

15
@IcyBlueRose - bundleIdentifier adalah objek autoreleased karena tidak dimulai dengan init atau baru, sehingga Anda akan melepaskannya secara berlebihan.
Christopher Rogers

1
Senang tahu, terima kasih! Tapi saya sedang berbicara tentang string appDomain. Apakah itu otomatis dirilis juga?
IcyBlueRose

2
@IcyBlueRose Objek yang dikembalikan oleh bundleIdentifier sama dengan objek yang dirujuk oleh appDomain.
Christopher Rogers

2
Saya sepertinya tidak bisa mengaktifkan ini pada 10.8 lagi, bisakah seseorang mengonfirmasi bahwa ini berhasil? Berikut pertanyaan SO terkait: stackoverflow.com/questions/13595415/…
DaGaMs

102

Kode ini mengatur ulang default ke domain pendaftaran:

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

Dengan kata lain, itu removeObjectForKeyuntuk setiap kunci tunggal yang pernah Anda daftarkan di aplikasi itu.

Penghargaan untuk Ken Thomases di utas Forum Pengembang Apple ini .


4
Terima kasih banyak. Mengapa [NSUserDefaults resetStandardUserDefaults]tidak melakukan ini di luar jangkauan saya.
jakeboxer

2
@jboxer Saya baru saja menghabiskan waktu mempelajari dokumentasi Apple dan mengatur ulangStandardUserDefaults pada dasarnya membersihkan buffer di dalam memori ke disk dan menghapusnya. Jadi lain kali Anda mencoba mengambil nilai itu harus mengambilnya dari disk. NSManagedObjectContext dari Core Data juga menggunakan terminologi "reset" yang serupa.
Christopher Rogers

2
Ups, maksud saya menghapus buffer di memori tanpa menuliskannya ke disk. Jadi setiap perubahan yang Anda buat sebelum sinkronisasi ke disk akan hilang.
Christopher Rogers

4
Christopher, saya pikir Anda memilikinya mundur walaupun mungkin semuanya berubah. resetStandardUserDefaults adalah panggilan paling membingungkan yang pernah saya lihat di iOS. Apple Documents mengatakan "Menyinkronkan setiap perubahan yang dilakukan pada objek default pengguna bersama dan melepaskannya dari memori." jadi itu harus benar-benar disebut flushAndReleaseStandardUserDefaults. Saya meluangkan waktu untuk mengomentari komentar lama karena saya baru saja tertangkap oleh panggilan ini dan ingin menghindari orang lain dibakar (sekarang saya harus memberi tahu klien bahwa saya perlu memperbarui 90 aplikasi).
Andy Dent

97

Apakah Anda mencoba menggunakan - removeObjectForKey?

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

Cheers sbooth. Banyak Dihormati.
TonyNeallon

5
Adakah cara untuk menghapus objek untuk semua kunci yang ada?
samvermette

2
Sementara saya mengerti ini tampaknya berfungsi, mengapa tidak defunctPreference semacam sistem yang didefinisikan konstan? Saya yakin akan gugup bahwa ini akan berhenti bekerja suatu saat nanti.
David H

Apakah Anda harus melakukan sinkronisasi setelah?
Travis M.

30

Inilah jawabannya di Swift:

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

8
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(NSBundle.mainBundle().bundleIdentifier!)one-liner
Grace Shao

3
Atau lebih aman:if let domainName = NSBundle.mainBundle().bundleIdentifier { NSUserDefaults.standardUserDefaults().removePersistentDomainForName(domainName) }
Valentin Shergin

1
Versi cepat dari Grace's oneliner:UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)
Carsten Hagemann

28

Jika Anda membutuhkannya saat mengembangkan, Anda juga dapat mengatur ulang simulator Anda, menghapus semua NSUserDefaults.

iOS Simulator -> Setel Ulang Konten dan Pengaturan ...

Ingatlah bahwa itu juga akan menghapus semua aplikasi dan file pada simulator.


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

7

Dalam Swift:

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

6

Catatan: Jawaban ini telah diperbarui untuk Swift juga.

Bagaimana kalau memilikinya di satu baris?

Extending @Christopher Rogers menjawab - yang diterima

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

dan ya, kadang-kadang Anda mungkin perlu synchronize,

[[NSUserDefaults standardUserDefaults] synchronize];

Saya telah membuat metode untuk melakukan ini,

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

Cepat ?

Dengan cepat bahkan lebih mudah.

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

Dan penggunaan :

UserDefaults.clean()

6

Saya suka ekstensi ketika mereka membuat kode lebih bersih:

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

        self.removePersistentDomainForName(domainName)
    }
}

Cepat 5

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


2

Semua jawaban di atas sangat relevan, tetapi jika seseorang masih tidak dapat mengatur ulang kesalahan pengguna untuk aplikasi yang dihapus, maka Anda dapat mengatur ulang pengaturan konten simulator Anda, dan itu akan berhasil.masukkan deskripsi gambar di sini


2

Ini bug atau apa pun tetapi removePersistentDomainForNametidak berfungsi saat membersihkan semua NSUserDefaultsnilai.

Jadi, pilihan yang lebih baik adalah mengatur ulang PersistentDomaindan yang dapat Anda lakukan melalui cara berikut:

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

1

Memperluas jawaban @ folse ... Saya yakin implementasi yang lebih tepat adalah ...

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];
    }

... memanggil metode persistentDomainForName: NSUserDefault. Sebagai status dokumen, metode "Mengembalikan kamus yang berisi kunci dan nilai dalam domain persisten yang ditentukan." Calling dictionaryRepresentation: sebagai gantinya, akan mengembalikan kamus yang kemungkinan akan mencakup pengaturan lain yang berlaku untuk cakupan yang lebih luas.

Jika Anda perlu menyaring salah satu nilai yang harus diatur ulang, maka iterasi tombol adalah cara untuk melakukannya. Tentunya, jika Anda ingin mengabaikan semua prefs untuk aplikasi tanpa memperhatikan, maka salah satu metode lain yang diposting di atas adalah yang paling efisien.



0

Coba ini, Ini bekerja untuk saya.

Baris kode tunggal

[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.