การล้าง NSUserDefaults


285

ฉันใช้+[NSUserDefaults standardUserDefaults]เพื่อจัดเก็บการตั้งค่าแอปพลิเคชัน สิ่งนี้ประกอบด้วยค่าสตริงประมาณโหล เป็นไปได้ไหมที่จะลบค่าเหล่านี้อย่างถาวรแทนที่จะตั้งเป็นค่าเริ่มต้น?


คำตอบ:


514

คุณสามารถลบโดเมนถาวรของแอปพลิเคชันเช่นนี้:

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

ใน Swift 3 และใหม่กว่า:

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

นี่คล้ายกับคำตอบของ @samvermette แต่เป็น IMO ที่สะอาดขึ้นเล็กน้อย


มันใช้งานได้ดีขอบคุณ! อย่าลืมปล่อยแอพโดเมนหลังจากนั้น
IcyBlueRose

15
@IcyBlueRose - bundleIdentifier เป็นออบเจ็กต์ที่เปิดอัตโนมัติเนื่องจากมันไม่ได้เริ่มต้นด้วย init หรือใหม่ดังนั้นคุณจะปล่อยมันมากเกินไป
Christopher Rogers

1
ดีใจที่ได้ทราบขอบคุณ! แต่ฉันกำลังพูดถึงแอปสตริงโดเมน เป็นรถยนต์ที่ปล่อยออกมาด้วยหรือไม่
IcyBlueRose

2
@IcyBlueRose วัตถุที่ส่งกลับมาโดย bundleIdentifier เหมือนกับวัตถุที่อ้างอิงโดย appDomain
Christopher Rogers

2
ดูเหมือนว่าฉันจะไม่สามารถใช้งานได้ใน 10.8 อีกต่อไปแล้วมีใครได้โปรดยืนยันว่างานนี้ได้หรือไม่ นี่คือคำถาม SO ที่เกี่ยวข้อง: stackoverflow.com/questions/13595415/…
DaGaMs

102

รหัสนี้รีเซ็ตค่าเริ่มต้นเป็นโดเมนการลงทะเบียน:

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

กล่าวอีกนัยหนึ่งก็คือ removeObjectForKeyสำหรับทุกคีย์เดียวที่คุณเคยลงทะเบียนในแอพนั้น

เพิ่มเครดิตให้กับ Ken Thomases ในกระทู้นักพัฒนา Apple นี้


4
ขอบคุณมัด ทำไม[NSUserDefaults resetStandardUserDefaults]ทำอย่างนี้ไม่ได้อยู่เหนือฉัน
jakeboxer

2
@jboxer ฉันเพิ่งใช้เวลาศึกษาเอกสารของ Apple และ resetStandardUserDefaults โดยทั่วไปจะล้างบัฟเฟอร์ในหน่วยความจำไปยังดิสก์และเช็ดทำความสะอาด ในครั้งต่อไปที่คุณพยายามดึงค่ามันจะต้องดึงมันมาจากดิสก์ NSManagedObjectContext ของ Core Data ยังใช้คำศัพท์ "รีเซ็ต" ที่คล้ายกัน
Christopher Rogers

2
โอ๊ะฉันหมายความว่ามันจะลบบัฟเฟอร์ในหน่วยความจำโดยไม่ต้องเขียนลงในดิสก์ ดังนั้นการเปลี่ยนแปลงใด ๆ ที่คุณทำก่อนซิงโครไนซ์กับดิสก์จะหายไป
Christopher Rogers

4
คริสโตเฟอร์ฉันคิดว่าคุณจะย้อนกลับไปถึงแม้ว่าสิ่งต่าง ๆ อาจมีการเปลี่ยนแปลง resetStandardUserDefaults เป็นการโทรที่สับสนที่สุดที่ฉันเคยเห็นใน iOS เอกสารของ Apple กล่าวว่า "ซิงโครไนซ์การเปลี่ยนแปลงใด ๆ ที่ทำกับวัตถุค่าเริ่มต้นของผู้ใช้ที่ใช้ร่วมกันและเผยแพร่จากหน่วยความจำ" ดังนั้นจึงควรเรียกว่า flushAndReleaseStandardUserDefaults จริงๆ ฉันสละเวลาในการแสดงความคิดเห็นในความคิดเห็นเก่าเพราะฉันเพิ่งถูกสายนี้และต้องการหลีกเลี่ยงการถูกคนอื่นถูกเผา (ตอนนี้ฉันต้องบอกลูกค้าว่าฉันต้องอัปเดต 90 แอพ)
Andy Dent

97

คุณลองใช้ - removeObjectForKey?

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

ไชโย ชื่นชมมาก
TonyNeallon

5
มีวิธีใดในการลบวัตถุสำหรับคีย์ที่มีอยู่ทั้งหมด
samvermette

2
ในขณะที่ฉันเข้าใจว่าสิ่งนี้ดูเหมือนจะใช้งานได้ทำไมไม่ defunctPreference ค่าคงที่ของระบบบางประเภท ฉันมั่นใจว่ามันจะหยุดทำงานในวันข้างหน้า
David H

คุณต้องซิงโครไนซ์หลังจากหรือไม่
Travis M.

30

นี่คือคำตอบใน Swift:

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

8
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(NSBundle.mainBundle().bundleIdentifier!)สายการบิน
Grace Shao

3
หรือปลอดภัยยิ่งขึ้น:if let domainName = NSBundle.mainBundle().bundleIdentifier { NSUserDefaults.standardUserDefaults().removePersistentDomainForName(domainName) }
Valentin Shergin

1
รุ่นที่รวดเร็วของ Grace's oneliner:UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)
Carsten Hagemann

28

NSUserDefaultsหากคุณจำเป็นต้องใช้มันขณะที่การพัฒนานอกจากนี้คุณยังสามารถตั้งค่าจำลองของคุณลบทั้งหมด

iOS Simulator -> รีเซ็ตเนื้อหาและการตั้งค่า ...

โปรดจำไว้ว่ามันจะลบแอพและไฟล์ทั้งหมดในเครื่องจำลอง


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

7

ในสวิฟท์:

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

6

หมายเหตุ: คำตอบนี้ได้รับการปรับปรุงสำหรับ Swift ด้วย

จะเกี่ยวกับอะไรในหนึ่งบรรทัด?

การขยายคำตอบ @Christopher Rogers - คำตอบที่ยอมรับได้

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

และใช่บางครั้งคุณอาจต้องการsynchronizeมัน

[[NSUserDefaults standardUserDefaults] synchronize];

ฉันได้สร้างวิธีการทำสิ่งนี้แล้ว

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

รวดเร็วหรือไม่

ด้วยความรวดเร็วมันง่ายยิ่งขึ้น

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

และการใช้งาน :

UserDefaults.clean()

6

ฉันชอบส่วนขยายเมื่อพวกเขาทำให้โค้ดสะอาดขึ้น:

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

        self.removePersistentDomainForName(domainName)
    }
}

สวิฟท์ 5

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


2

คำตอบทั้งหมดข้างต้นมีความเกี่ยวข้องมาก แต่ถ้ามีคนยังไม่สามารถรีเซ็ต userdefaults สำหรับแอปที่ลบแล้วคุณสามารถรีเซ็ตการตั้งค่าเนื้อหาของคุณจำลองและมันจะทำงานป้อนคำอธิบายรูปภาพที่นี่


2

มันเป็นข้อบกพร่องหรืออะไรก็ตาม แต่removePersistentDomainForNameมันไม่ทำงานในขณะที่ล้างNSUserDefaultsค่าทั้งหมด

ดังนั้นตัวเลือกที่ดีกว่าคือการรีเซ็ตPersistentDomainและคุณสามารถทำได้ผ่านวิธีต่อไปนี้:

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

1

ขยายคำตอบของ @ folse ... ฉันเชื่อว่าการนำไปปฏิบัติที่ถูกต้องมากขึ้นจะเป็น ...

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

... เรียกใช้เมธอด persistentDomainForName: NSUserDefault ในขณะที่สถานะเอกสารวิธี "ส่งคืนพจนานุกรมที่มีคีย์และค่าในโดเมนถาวรที่ระบุ" การเรียกใช้พจนานุกรมการนำเสนอ: แต่จะส่งคืนพจนานุกรมที่น่าจะรวมถึงการตั้งค่าอื่น ๆ แทนซึ่งจะใช้กับขอบเขตที่กว้างขึ้น

หากคุณต้องการกรองค่าใด ๆ ที่จะถูกรีเซ็ตการทำซ้ำคีย์จะเป็นวิธีที่ทำได้ เห็นได้ชัดว่าถ้าคุณต้องการเพียงแค่ prefs ทั้งหมดสำหรับแอปโดยไม่คำนึงถึงวิธีการอื่นที่โพสต์ข้างต้นนั้นมีประสิทธิภาพมากที่สุด


0

หากการตั้งค่าแอปพลิเคชันที่ต้องการรีเซ็ตเป็น nsuserdefault สำหรับการเข้าถึงไมโครโฟน (กรณีของฉัน) คำตอบง่ายๆจาก Anthony McCormick ( iPhone - วิธีการเปิดใช้งานแอปพลิเคชันเข้าถึงสื่อบนอุปกรณ์ - ALAssetsLibraryErrorDomain Code = -3312 )

บนอุปกรณ์ให้ไปที่การตั้งค่า> ทั่วไป> รีเซ็ต> รีเซ็ตคำเตือนตำแหน่ง


0

ลองสิ่งนี้มันใช้งานได้สำหรับฉัน

รหัสบรรทัดเดียว

[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.