CoreData 并发和释放对象
Posted
技术标签:
【中文标题】CoreData 并发和释放对象【英文标题】:CoreData concurrency and releasing objects 【发布时间】:2016-07-12 08:56:28 【问题描述】:我目前正在验证我们在多线程环境中使用的新 CoreData 架构。为了进行分析,我使用GDCoreDataConcurrencyDebugging 打印警告,每次从错误的线程/队列访问 ManagedObject(据我所知)。
现在我收到大量这样的警告:
Invalid concurrent access to managed object calling 'release'
我能够在生成警告的地方放置一个断点,代码如下所示:
-(MyObject*) createMyObject
return (MyObject*)[self insertNewObjectEntityWithName:@"MyObject"];
-(NSManagedObject*) insertNewObjectEntityWithName:(NSString*) entityName
__block NSManagedObject *managedObject;
[self.managedObjectContext performBlockAndWait:^(void)
managedObject = [NSEntityDescription insertNewObjectForEntityForName:entityName
inManagedObjectContext:self.managedObjectContext];
];
return managedObject;
它在返回后打破了createMyObject
-method,我猜这是在释放对象时。 CoreData-concurrency 和 object-release 有什么特别之处吗?
我环顾四周,没有提到任何关于对象释放的内容,只有关于我没有使用的自动释放池。
【问题讨论】:
【参考方案1】:您正在通过performBlockAndWait:
调用执行工作,这是正确的。但是,您继续返回对象,可能来自不同的线程。那是不合法的。所有托管对象都必须从创建它们的线程/队列中访问,objectID
属性除外,该属性始终有效。
【讨论】:
感谢您的快速回复。所以基本上我不允许从我的执行块中给出任何对象? 正确。通常的做法是使用从同一上下文中调用的完成块,或者传递objectID
s 并重新获取到不同的上下文中。
哦,真可惜。我认为我们将不得不改造我们的很多软件架构。非常感谢【参考方案2】:
请使用此代码获取 managedObjectContext 。托管对象必须从创建它们的线程/队列中访问。
- (NSManagedObjectContext *)managedObjectContext
NSThread *thisThread = [NSThread currentThread];
if (thisThread == [NSThread mainThread])
if (_managedObjectContext != nil)
return _managedObjectContext;
//
if ([self persistentStoreCoordinator] != nil)
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_managedObjectContext setPersistentStoreCoordinator:[self persistentStoreCoordinator]];
[_managedObjectContext setRetainsRegisteredObjects:YES];
[_managedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
return _managedObjectContext;
else
//Return separate MOC for each new thread
NSManagedObjectContext *threadManagedObjectContext = [[thisThread threadDictionary] objectForKey:@"MOC_KEY"];
if (threadManagedObjectContext == nil)
threadManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
[threadManagedObjectContext setPersistentStoreCoordinator: coordinator];
[[thisThread threadDictionary] setObject:threadManagedObjectContext forKey:@"MOC_KEY"];
return threadManagedObjectContext;
【讨论】:
我已经实现了类似的东西。这似乎不是这里的问题,而是@Avi 指出的架构误解。以上是关于CoreData 并发和释放对象的主要内容,如果未能解决你的问题,请参考以下文章
Coredata 和 Mogenerator,coredata 标志并发问题 EXC_BAD_INSTRUCTION