NSUserDefaults setObject在Thread中崩溃

Mat*_*att -2 crash nsuserdefaults ios ios9

我在后台做一些事情.我也尝试将对象写入标准用户默认值.从iOS 9开始,它就崩溃了.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

// calling some methods in the background
// also save a value to the user defaults
NSDate *aDate = [NSDate date];
[[NSUserDefaults standardUserDefaults] setObject:aDate forKey:@"date"]; // <-- crash: EXC_BAD_ACCESS

});
Run Code Online (Sandbox Code Playgroud)

我找不到问题.aDate不是零.我也尝试在主线程(来自后台线程)上执行setObject:但结果相同.

崩溃是零星的!我做错了什么?

这是堆栈跟踪:

崩溃:com.apple.root.background-qos EXC_BAD_ACCESS KERN_INVALID_ADDRESS位于0x0000000000000010

线程:崩溃:com.apple.root.background-qos 0 libobjc.A.dylib
0x0000000199b0dbd0 objc_msgSend + 16 1基础
0x0000000185ea1eb4 - [NSObject(NSKeyValueObserverNotification)willChangeValueForKey:] + 324 2 CoreFoundation
0x0000000185090994 _CFPreferencesSetValueWithContainer + 168 3 Foundation 0x0000000185eb9138 - [NSUserDefaults( NSUserDefaults)setObject:forKey:] + 56 4 AIR 0x00000001000f201c - [ServerSyncAgent syncUnsyncedEntities](ServerSyncAgent.m:212)5 libdispatch.dylib
0x000000019a2e97b0 _dispatch_call_block_and_release + 24 6 libdispatch.dylib 0x000000019a2e9770 _dispatch_client_callout + 16 7 libdispatch.dylib 0x000000019a2f7bb0 _dispatch_root_queue_drain + 2140 8 libdispatch.dylib 0x000000019a2f734c _dispatch_worker_thread3 + 112 9 libsystem_pthread.dylib 0x000000019a4fd478 _pthread_wqthread + 1092

Nik*_*uhe 5

来自Apple的文档:

NSUserDefaults类是线程安全的.

发布的代码很好.您的错误在其他地方.

编辑:堆栈指出您的错误来源:

您的代码中的其他地方(或某些第三方库)正在添加KVO观察者[NSUserDefaults standardUserDefaults].然而,NSUserDefaults不符合KVO,所以你不能添加观察者.

如果需要对用户默认值的更改做出反应,则必须使用NSNotificationCenter并注册NSUserDefaultsDidChangeNotification.

第2次编辑:不确定何时更改但在现代iOS和macOS中NSUserDefaults是Key-Value可观察的.上面链接的相同文档现在明确指出:

您可以使用键值观察来注册感兴趣的特定键的观察者,以便获得对本地默认数据库的所有更新的通知.有关更多详细信息,请参阅键值观察编程指南.