核心数据 - 删除持久存储时死锁

时间:2013-01-19 17:15:52

标签: ios core-data

是否有一种安全的方法可以在应用程序中删除持久存储(并创建一个新的存储),其他线程正在使用与正在删除的存储相关联的NSManagedObjectContext?我已经尝试锁定NSPersistentStoreCoordinator并在操作结束后解锁它,但它没有帮助 - 我所有的尝试都导致了死锁。它总是发生在这一行上(在主线程上执行):

[self.persistentStoreCoordinator removePersistentStore: store error: &error];

3 个答案:

答案 0 :(得分:2)

我没有尝试过,但是来自docs on moc setPersistentStoreCoordinator: ...

  

协调器提供托管对象模型和句柄   持久性。请注意,多个上下文可以共享协调器。

     

如果协调器为零,则此方法引发异常。如果你想   “断开”来自其持久性商店协调员的上下文   应该简单地将对上下文的所有强引用设置为nil和   允许它正常解除分配。

这表明删除psc的安全方法是首先让每个带有moc的线程释放它(在ARC中对它进行nil-out引用),然后执行removePersistentStore:

答案 1 :(得分:1)

我会尝试使用此处描述的方法(父/子上下文部分): Multi-Context CoreData

基本上,您的PSC只有一个与之关联的MOC(父MOC)。其他线程有自己的MOC,其parentContext设置为主MOC(与PSC关联的MOC)。

然后你可以尝试这样的事情:

// Save each child MOC
for (NSManagedObjectContext *moc in self.someChildMOCs)
{
   [moc performBlockAndWait:^{

       // push to parent
       NSError *error;
       NSAssert([moc save:&error]);
       moc.parentContext = nil;
   }];
}

// Save parent MOC to disk
[self.mainMOC performBlockAndWait:^{
   NSError *error;
   NSAssert([mainMOC save:&error]);
}];

[self.persistentStoreCoordinator removePersistentStore:store error:&error];
mainMOC.persistentStoreCoordinator = nil;

答案 2 :(得分:1)

  

是否有一种安全的方法可以在应用程序中删除持久存储(并创建一个新的存储),其他线程正在使用与正在删除的存储相关联的NSManagedObjectContext?

如果您可以保证没有实时托管对象将尝试访问持久性存储,那么它应该是安全的。这一部分至关重要:您必须确保没有任何类型的活动对象从旧的持久性存储中加载或与之相关联。

您可以通过重置每个托管对象上下文来执行此操作:

[managedObjectContext performBlockAndWait:^{
    [managedObjectContext reset];
}];

每个托管对象上下文完成此操作后,您可以删除持久性存储。

请注意,如果您有从这些上下文中提取的任何托管对象,则必须立即处理它们,而无需读取或写入属性值或以任何方式使用它们。由于各种原因,这些对象可能需要使用上下文,但在调用reset之后,上下文不再了解它们。立即摆脱它们(理想情况下甚至在调用重置之前),因为它们是时间炸弹等待你触摸它们时炸毁你的应用程序。