NSUserDefaults setObject:forKey 死锁?

Posted

技术标签:

【中文标题】NSUserDefaults setObject:forKey 死锁?【英文标题】:NSUserDefaults setObject:forKey deadlocks? 【发布时间】:2015-07-09 14:18:02 【问题描述】:

今天遇到一个比较困惑的问题:

当我的应用程序启动时,我正在下载一些东西,并在解析响应后将数据写入 NSUserDefaults。 现在这工作正常,直到我最近发现有时我的整个 UI 冻结并且在我重新启动应用程序之前不会解冻。当我在调试器中点击暂停程序执行时,我得到:

文档说 NSUserDefaults 是线程安全的,据我所知,没有其他线程正在尝试访问用户默认值...

任何关于如何解决/进一步调试问题的想法将不胜感激!

提前致谢!

导致问题的代码:

这在我收到 web 服务的响应后调用:

+ (void)updateWithData:(NSData *)data

    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

    NSError *error;
    NSArray *decodedData;

    if (data) 
        decodedData = [NSPropertyListSerialization propertyListWithData:data
                                                            options:NSPropertyListImmutable
                                                             format:NULL
                                                              error:&error];
    

    if (!error && decodedData) 
        [userDefaults setObject:decodedData forKey:kUserDataUserDefaultsKey];
    
    else
        NSLog(@"%@", error.localizedDescription);
    

【问题讨论】:

你能提供一些代码吗? NSUserDefaults 是线程安全的,因为当调用 setValue: forKey: 时,它会锁定对包含值的字典的访问。 您找到这个问题的原因了吗?我在同时使用 NSUserDefaults 时遇到了类似的死锁。 我遇到了类似的问题,我的问题是特定于设备的。在模拟器和大多数其他手机上没有问题,但在 iPhone 5s 上。我认为这是一个时间问题。如果我能把在某个地方延迟清理它? ios 11.2.5 上仍然不时发生 【参考方案1】:

更新了新的代码示例:

您应该将 decodedData 转换为存档数据,以便将其存储在 NSUserDefaults 中:

if (!error && decodedData) 
    NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject: decodedData]];
    [userDefaults setObject: archivedData forKey:kUserDataUserDefaultsKey];

然后用这个来检索数据:

NSArray *storedData = [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:kUserDataUserDefaultsKey]];

【讨论】:

这很有趣.. 你认为这就是锁定的原因吗? @Subbu 我会说这更像是一个“用火杀死它”的解决方案,假设问题是由传递的数据不符合 NSCoding 协议引起的。 @thattyson 感谢您的回答!但是我几乎不认为这会导致锁定。在 propertyListWithData:... 返回后,他 decodedData 数组只包含符合 NSCoding...的 NSString 对象... 大部分时间它都在工作。只是有时线程似乎死锁了...... @DavidSilverfarmer 啊,我想我读错了你的问题;没有意识到它只是在某些时候冻结。

以上是关于NSUserDefaults setObject:forKey 死锁?的主要内容,如果未能解决你的问题,请参考以下文章

NSUserDefaults setObject:forKey 死锁?

NSUserDefaults setObject 方法导致应用在 ios8 中崩溃

NSUserDefaults存取失败

NSUserDefaults的使用

同步 NSUserDefaults 没有效果

使用常量 NSString 作为 NSUserDefaults 的键