我使用这样的核心数据:
- (NSManagedObjectContext *)managedObjectContext {
@synchronized(self) {
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_managedObjectContext = [NSManagedObjectContext new];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}
}
return _managedObjectContext;
}
- (NSManagedObjectModel *)managedObjectModel {
@synchronized(self) {
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
NSString *path = [[NSBundle mainBundle] pathForResource:@"DB" ofType:@"momd"];
if (path) {
NSURL *momURL = [NSURL fileURLWithPath:path];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];
}
}
return _managedObjectModel;
}
但有时我会崩溃: 集合< __ NSCFSet:0x14c5bffdq>在被列举时被突变。 怎么了?如何使用多线程核心数据?
答案 0 :(得分:0)
当您在for循环或while循环中变异或更改核心数据实体时,会发生此崩溃。像这样的东西
for(NSManageObject *obj in someArray){
[context deleteObject:someArray];
}
由于崩溃,您可能必须更改您想要实现的目标的逻辑。
现在,如果您想在后台模式下执行Core数据,有一些方法可以做到这一点。
亲子上下文就是其中之一,您可以在其中创建子上下文并完成performBlock
中的所有工作并推送保存更改,因为它会自动推送更改回父MOC。
在异步单例队列中操作,但在主队列中执行更改或saveContext
。您还可以使用NSOperationQueue
交换队列,并创建一个单例。
这样,您可以在后台执行Core Data操作,因为您不要冻结UI。
一切都取决于你想做什么以及你想要达到的目标。在更广泛的方面,我建议去寻找亲子背景。它非常强大,可以解决您的Core Data多线程问题。
请查看this答案,了解核心数据中父子环境的正确实施。
答案 1 :(得分:0)
*- (NSManagedObjectContext *)managedObjectContext
{
DDLogTrace();
if (__managedObjectContext != nil) {
return __managedObjectContext;
}
dispatch_block_t initBlock = ^{
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
__managedObjectContext = [[NSManagedObjectContext alloc] init];
}
};
if ([NSThread isMainThread]) {
initBlock();
}else{
dispatch_sync(dispatch_get_main_queue(), initBlock);
}
return __managedObjectContext;
}*
Try this , many time thread swich and NSManagedObjectContext create in secondary or background thread .
NSManagedObjectContext always execute in main thread