我有一个非常奇怪的崩溃,不知道我做错了什么。这是代码。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
Contact *contact = [Contact MR_findFirstByAttribute:kCoreData_Contact_ID withValue:strContactID inContext:localContext];
strFilePath = [Util buildFilePathForImageWithID:contact.c_id withKey:@"ContactPicture"];
contact.c_photoFilePath = strFilePath;
} completion:^(BOOL success, NSError *error) {
}];
Contact *contact = [Contact getContactWithID:strContactID];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:contact.c_photoURL]];
[data writeToFile:strFilePath atomically:YES];
UIImage *image = [UIImage imageWithData:data];
UIImage *imgToShow = nil;
if (image)
{
imgToShow = [SquareAndMask maskImage_72:image];
}
else
{
imgToShow = [UIImage imageNamed:@"add_rv_photo"];
}
dispatch_async(dispatch_get_main_queue(), ^{
//> Image downloaded, load it
[self.imgViewPhoto setImage:imgToShow];
self.imgViewStatusLevel.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@_btn",contact.c_status]];
});
});
目前我脑子里有一些关于多线程与MR的混淆,这就是上述代码可能存在问题的原因。但是,我无法理解为什么会崩溃。
注意:我在模拟器上测试,在iPad mini视网膜上测试,对我来说,没有崩溃。我的客户正在iPad 3,4上进行测试,当这部分代码运行时,他就崩溃了。
我在这段代码中做了什么:我有一个Contact对象,它保存了照片的url和filePath。所以第一次,没有本地保存的图像,我运行此代码,下载图像,并在本地保存,我还保存了一个c_photoFilePath,所以下次我知道从哪里拍摄该图像。
我象征着一些崩溃日志,这就是我得到的:
此外,一旦我在模拟器中得到它,机器人不确定它是否与此崩溃有关:
CoreData: error: Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. -[__NSCFSet addObject:]: attempt to insert nil with userInfo (null)
我接受上述代码的任何诅咒:)请帮助我。
答案 0 :(得分:2)
第一条经验法则建议:如果你有随机崩溃的代码,你可能会错误地演唱线程或并发。
其次,你在这里做的是在后台调度一个调度。 saveWithBlock方法立即返回。它之后的代码需要同步结果,并且可能因为您的数据尚未就绪而崩溃。您也没有正确地与核心数据交叉线程边界。我建议查看MagicalRecord库中的MR_inContext:方法。至于修复,我建议不要使用dispatch包装saveWithBlock调用。此外,在完成块中准备好数据后,将要运行的所有代码放入。这就是它的用途。