在 Core Data 中从 AppDelegate 执行回滚功能时需要访问 ManagedObjectContext 的同一实例
Posted
技术标签:
【中文标题】在 Core Data 中从 AppDelegate 执行回滚功能时需要访问 ManagedObjectContext 的同一实例【英文标题】:Need access to same instance of ManagedObjectContext when performing rollback functionality from AppDelegate in Core Data 【发布时间】:2015-02-12 19:43:43 【问题描述】:在我的 ios 应用程序中,我使用 Core Data 来获取和删除一个非常大的数据集。此过程大约需要 5-10 秒。我想做的是执行回滚,以防用户决定在该过程完成之前关闭设备。但是,问题是让 NSManagedObjectContext 的 SAME 实例从适当的 AppDelegate 方法调用回滚函数。在我的应用程序中,我使用这样的 Singleton 对象调用我的核心数据方法:
static MySingleton *sharedSingleton = nil;
+ (MySingleton *) sharedInstance
if (sharedSingleton == nil)
sharedSingleton = [[super alloc] init];
return sharedSingleton;
在我的应用程序中,我返回一个 NSManagedObjectContext 的实例,如下所示:
- (NSManagedObjectContext *) managedObjectContext
if (_managedObjectContext != nil)
return _managedObjectContext;
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil)
_managedObjectContext = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSMainQueueConcurrencyType];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
//Undo Support
NSUndoManager *anUndoManager = [[NSUndoManager alloc] init];
[self.managedObjectContext setUndoManager:anUndoManager];
return _managedObjectContext;
然后我调用它,并将它分配给这样的引用:
NSManagedObjectContext *context = [[MySingleton sharedInstance] managedObjectContext];
如何使这个 ManagedObjectContext 实例可供我在 AppDelegate 中使用,以便我可以调用回滚函数?
【问题讨论】:
【参考方案1】:首先,创建单例的更好(更安全)方法如下所示:Create singleton using GCD's dispatch_once in Objective C,即:
+ (instancetype)sharedInstance
static dispatch_once_t once;
static id sharedInstance;
dispatch_once(&once, ^
sharedInstance = [[self alloc] init];
);
return sharedInstance;
接下来,由于您创建了一个必须停留几秒钟的托管对象上下文,因此您必须在某处对其进行强引用。
如果您正在调试并且对代码的一些基本假设提出质疑,请为托管对象上下文命名(或记录 MOC 指针的内存地址),以便稍后在调试器中进行检查,亲自验证一下,您确实在处理同一个问题。
还请注意,如果您仅为此类导入创建了专用的托管对象上下文,则无需回滚它。你可以直接丢弃它。
在我的应用程序中,我通常有一个父(根)托管对象上下文和几个子上下文;一个子用于主线程,另一个子用于导入类型操作。
【讨论】:
【参考方案2】:作为替代解决方案,您可以创建一个多上下文场景,而不是回滚更改,在该场景中,子托管对象上下文添加您需要的所有数据,最终完成后,您保存将新数据发送到的子上下文主要管理对象。这样,在整个过程完成之前,主托管对象上下文不会受到影响。
这是一篇很棒的文章作为参考Multi-Context CoreData。
基本上你需要做的是
// create main MOC
_mainContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_mainContext setPersistentStoreCoordinator:_persistentStoreCoordinator];
// create child MOC
_childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
_childContext.parentContext = _mainContext;
希望对您有所帮助。
【讨论】:
以上是关于在 Core Data 中从 AppDelegate 执行回滚功能时需要访问 ManagedObjectContext 的同一实例的主要内容,如果未能解决你的问题,请参考以下文章
在 Swift Core Data 中从一对多关系中获取对象
如何在 Swift 中从 Core Data 中删除数据时删除 UITableView 行?
在 Core Data 中从 AppDelegate 执行回滚功能时需要访问 ManagedObjectContext 的同一实例
如何在 Swift 中从 Core Data 访问子数据和父数据
Singleton 类 DataLoader - 在 AppDelegate 中从 Core Data 设置值,但无法访问其他类中的 DataLoader 变量