7

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

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

3 回答 3

2

我还没有尝试过,但是从moc 上的文档中 setPersistentStoreCoordinator:...

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

如果 coordinator 为 nil,则此方法引发异常。如果你想从它的持久存储协调器“断开”一个上下文,你应该简单地将所有对上下文的强引用设置为 nil 并允许它被正常释放。

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

于 2014-05-05T17:22:59.670 回答
1

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

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

您可以通过重置每个托管对象上下文来做到这一点:

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

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

请注意,如果您有任何从这些上下文中获取的托管对象,则必须立即处置它们,而不读取或写入属性值或以任何方式使用它们。这些对象可能出于各种原因需要使用上下文,但在调用reset上下文之后,它们就不再了解它们了。立即摆脱它们(最好是在调用 reset 之前),因为它们是定时炸弹,等着你一碰就炸毁你的应用程序。

于 2014-05-05T20:57:44.167 回答
1

我会尝试使用此处描述的方法(Parent/Child Contexts部分): 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;
于 2014-05-05T17:23:52.473 回答