我有一个存储在NSUserDefaults
的对象队列。当我需要向其添加对象时,我调用以下方法:
+ (void)addCodeToQueue:(Code *)code {
// Note: userDefaults is a static, initialized variable
NSDictionary *codeModel = [self generateCodeModelWith:code];
// Read array from UserDefaults, or create one if nil
NSMutableArray *codeQueue = [userDefaults mutableArrayValueForKey:@"CodeQueue"] ? : [[NSMutableArray alloc] init];
// Add code model
[codeQueue addObject:codeModel];
// Add/replace array & sync
[userDefaults setObject:codeQueue forKey:@"CodeQueue"]; // App freezes here if uncommented
[userDefaults synchronize];
}
当我致电setObject:forKey
时,我的应用会冻结。如果我在该行添加一个断点,继续运行,它就可以了。如果我不打破,它会冻结。
在我将Xcode更新到版本8并开始使用新SDK之后,这种情况就开始发生了。 有关于此的任何提示吗?
答案 0 :(得分:15)
我在几个应用程序中也遇到了这个问题 - 看起来通过mutableArrayValueForKey返回可变数组,你可能会陷入互斥锁。对于我的代码,我把它换成了:
...对我来说,至少,这已经修复了互斥锁问题。
答案 1 :(得分:1)
在我的实验之后,我找到了生成互斥锁所需的最少代码。 代码如下。
NSMutableArray *videoArray = [[NSUserDefaults standardUserDefaults] mutableArrayValueForKey:VIDEOKEY];
[videoArray addObject:item];
[[NSUserDefaults standardUserDefaults] setObject:videoArray forKey:VIDEOKEY];
有三点需要注意:
[videoArray addObject:item];
,则应用会崩溃。[[NSUserDefaults standardUserDefaults] setObject:videoArray forKey:VIDEOKEY];
。[videoArray addObject:item];
处创建断点,则互斥锁仍然存在。如果我在[[NSUserDefaults standardUserDefaults] setObject:videoArray forKey:VIDEOKEY];
处进行,则互斥锁将不存在。 可以推断,互斥锁是[NSKeyValueSlowMutableArray addObject:];
和[NSUserDefaults setObject:forKey:]
顺便说一句,我的解决方法如下:
NSMutableArray *mutableVideoArray;
NSArray *videoArray = [[NSUserDefaults standardUserDefaults] arrayForKey:VIDEOKEY];
if (videoArray)
mutableVideoArray = [videoArray mutableCopy];
else
mutableVideoArray = [NSMutableArray array];
if (![mutableVideoArray containsObject:item])
{
[mutableVideoArray addObject:item];
[[NSUserDefaults standardUserDefaults] setObject:mutableVideoArray forKey:VIDEOKEY];
}