以下代码在没有最后一个语句的情况下运行良好。但是,在最后一行,Xcode停止并显示以下消息:
CoreData` + [的NSManagedObjectContext 的 Multithreading_Violation_AllThatIsLeftToUsIsHonor ]:
NSManagedObjectContext *context = GLOBAL_appDelegate.coreDataHelper.contextBackground;
[context performBlock:^{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"CdTag" inManagedObjectContext:context]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"title BEGINSWITH[cd] %@", @"webpages"];
[fetchRequest setPredicate:predicate];
NSArray *cdTags = [context executeFetchRequest:fetchRequest error:nil];
NSLog(@"number of tags: %li", cdTags.count);
CdTag *cdTag = [cdTags objectAtIndex:0];
// Accessing a property causes the assertion warning to be shown
cdTag.title;
}];
我正在使用Xcode 7 beta 5并启用了多线程断言。
上下文定义如下:
_model = [NSManagedObjectModel mergedModelFromBundles:nil];
_coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:_model];
_context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_context setPersistentStoreCoordinator:_coordinator];
_contextBackground = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_contextBackground setParentContext:_context];
这是一个Xcode错误还是我做错了什么?
答案 0 :(得分:5)
您能否在上下文初始化时添加代码?
您获得的错误与从初始化的线程/队列之外的线程/队列访问托管对象上下文有关。
通常会发生的事情是使用默认/遗留“限制类型”并发类型初始化托管对象上下文
performBlock:
和
performBlockAndWait:
方法实际上不会做他们做广告的事情,即确保在初始化时与其关联的队列上访问上下文。
如果我上面提到的是实际发生的事情你可以(假设其他一切都已到位)通过初始化你的上下文来解决这个问题:
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
或
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
以下是并发策略的文档:
使用initWithConcurrencyType:创建托管对象上下文时,您的线程(队列)关联有三个选项
限制(NSConfinementConcurrencyType)
为了向后兼容,这是默认设置。您保证除了您创建它之外的任何线程都不会使用上下文。通常,为了使行为明确,我们鼓励您使用其他类型之一。
如果托管对象上下文的父存储是持久性存储协调器,则只能使用此并发类型。
专用队列(NSPrivateQueueConcurrencyType)
上下文创建并管理专用队列。
主队列(NSMainQueueConcurrencyType)
上下文与主队列相关联,因此与应用程序的事件循环相关联,但它在其他方面类似于基于私有队列的上下文。您可以将此队列类型用于链接到控制器和UI对象的上下文,这些对象只需要在主线程上使用。
如果您使用限制模式使用上下文,则直接发送上下文消息;由您来确保从正确的队列发送消息。
使用基于队列的并发类型与performBlock:和performBlockAndWait结合使用上下文:。
作为旁注,你得到的错误信息是仍然站在Cocoa内的最后几个“复活节彩蛋”之一。
答案 1 :(得分:1)
构建iOS 9.0时不再出现此问题。