You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NSUserDefaults常规读取偶发崩溃原因排查与解决咨询

Fixing NSUserDefaults Spontaneous Crash on Main Thread

Hey there, let's tackle this tricky NSUserDefaults crash you're seeing. First off, that stack trace definitely points to a low-level system issue—since it's happening in CoreFoundation/libswiftCore during string comparison for a defaults lookup, and you've ruled out thread safety (since it's on the main thread, and NSUserDefaults is supposed to be thread-safe). Here's what you can do on your end, plus how to report this to Apple:

Temporary Workarounds to Mitigate Crashes

Since this seems like an Apple framework bug, your goal is to add safeguards around your NSUserDefaults calls to catch or avoid the crash:

  1. Wrap Calls in Objective-C Exception Handling
    Swift's native do/catch doesn't handle NSExceptions, but since your code is called from Objective-C, you can use Objective-C's exception wrapping to catch unexpected crashes when accessing the value. Also, adding an explicit lock (even though NSUserDefaults claims thread safety) might help in edge cases where the system's internal locking is failing:

    fileprivate static let userDefaults = UserDefaults.standard
    fileprivate static let PersistedBoolKey = "persistedBool"
    
    public var persistedBool: Bool {
        get {
            var result = false
            objc_sync_enter(Self.userDefaults)
            defer { objc_sync_exit(Self.userDefaults) }
            
            // Use Objective-C exception handling to catch unexpected crashes
            @objc try {
                result = Self.userDefaults.bool(forKey: Self.PersistedBoolKey)
            } @objc catch let exception as NSException {
                // Log the exception for debugging
                NSLog("Failed to read persistedBool: \(exception.name.rawValue), \(exception.reason ?? "No reason")")
                result = false
            }
            return result
        }
        set(newPersistedBool) {
            objc_sync_enter(Self.userDefaults)
            defer { objc_sync_exit(Self.userDefaults) }
            Self.userDefaults.set(newPersistedBool, forKey: Self.PersistedBoolKey)
            // Force sync (not usually recommended, but may help with inconsistent state)
            Self.userDefaults.synchronize()
        }
    }
    
  2. Validate Value Type Before Access
    If for some reason the value stored under your key got corrupted (e.g., another part of the app or a third-party library overwrote it), converting directly with bool(forKey:) could trigger a crash. Validate the type first, and clean up invalid values:

    get {
        objc_sync_enter(Self.userDefaults)
        defer { objc_sync_exit(Self.userDefaults) }
        
        guard let value = Self.userDefaults.object(forKey: Self.PersistedBoolKey) as? Bool else {
            // Remove invalid value to prevent future crashes
            Self.userDefaults.removeObject(forKey: Self.PersistedBoolKey)
            return false
        }
        return value
    }
    
  3. Use a Unique Key Prefix
    Ensure your key doesn't collide with system or third-party keys by adding a unique prefix (e.g., your app bundle ID):

    fileprivate static let PersistedBoolKey = "com.yourcompany.yourapp.persistedBool"
    

Reporting the Bug to Apple

Since this appears to be a low-level framework issue, you should report it directly to Apple:

  • Go to the Feedback Assistant and submit a bug report. Include:
    • Full crash logs (symbolicated if possible)
    • Your code snippet showing how you access NSUserDefaults
    • Xcode version (9.1)
    • List of iOS versions where the crash occurred (even if not specific)
    • Context about when the crash happens (e.g., app launch, background-foreground transition)
  • You can also post in the Apple Developer Forums (under the iOS > Foundation section) to see if other developers have encountered the same issue—sometimes you'll get workarounds or confirmation that Apple is aware.

Have Others Seen This?

Yes, several developers reported similar NSUserDefaults crashes after upgrading to Xcode 9.x, particularly in Swift/Objective-C interop scenarios. The common thread is spontaneous EXC_BAD_ACCESS in CoreFoundation during defaults lookups, which points to a memory management edge case in the system frameworks. Many found that the workarounds above (locking, exception handling) reduced or eliminated crashes while Apple fixes the underlying issue.

内容的提问来源于stack exchange,提问作者eli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:19:06