从 Core Data 中的 AppDelegate 执行回滚功能时需要访问相同的 ManagedObjectContext 实例
Need access to same instance of ManagedObjectContext when performing rollback functionality from AppDelegate in Core Data
在我的 iOS 应用程序中,我使用核心数据来获取和删除一个非常大的数据集。此过程大约需要 5-10 秒。我想做的是执行回滚,以防用户决定在该过程完成之前关闭设备。但是,问题是让 NSManagedObjectContext 的 SAME 实例从适当的 AppDelegate 方法调用回滚函数。在我的应用程序中,我使用像这样的 Singleton 对象调用我的核心数据方法:
static MySingleton *sharedSingleton = nil;
+ (MySingleton *) sharedInstance {
if (sharedSingleton == nil) {
sharedSingleton = [[super alloc] init];
}
return sharedSingleton;
}
在我的应用程序中,我 return 一个像这样的 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 中使用,以便我可以调用回滚函数?
作为替代解决方案,您可以创建一个多上下文场景,而不是回滚更改,在该场景中,子托管对象上下文添加您需要的所有数据,最终完成后,您保存子上下文发送新的数据到主要的管理对象。这样,在完成整个过程之前,主要的托管对象上下文不会受到影响。
这篇文章很棒,可以作为参考 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;
希望对您有所帮助。
首先,创建单例的更好(更安全)的方法是此处给出的示例: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;
}
接下来,由于您已经创建了一个必须停留几秒钟的托管 object 上下文,因此您必须在某处对它有一个强引用,而您确实这样做了。
如果您正在进行调试并质疑有关代码的一些基本假设,请为托管 object 上下文命名(或记录 MOC 指针的内存地址),您可以稍后在调试器中检查,以验证您确实在处理同一个调试器。
另请注意,如果您仅为此类导入创建了专用的托管 Object 上下文,则无需将其回滚。你可以直接丢弃它。
在我的应用程序中,我通常有一个 parent(root)管理的 object 上下文和几个 child 上下文;一个 child 用于主线程,另一个 child 用于导入类型操作。
在我的 iOS 应用程序中,我使用核心数据来获取和删除一个非常大的数据集。此过程大约需要 5-10 秒。我想做的是执行回滚,以防用户决定在该过程完成之前关闭设备。但是,问题是让 NSManagedObjectContext 的 SAME 实例从适当的 AppDelegate 方法调用回滚函数。在我的应用程序中,我使用像这样的 Singleton 对象调用我的核心数据方法:
static MySingleton *sharedSingleton = nil;
+ (MySingleton *) sharedInstance {
if (sharedSingleton == nil) {
sharedSingleton = [[super alloc] init];
}
return sharedSingleton;
}
在我的应用程序中,我 return 一个像这样的 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 中使用,以便我可以调用回滚函数?
作为替代解决方案,您可以创建一个多上下文场景,而不是回滚更改,在该场景中,子托管对象上下文添加您需要的所有数据,最终完成后,您保存子上下文发送新的数据到主要的管理对象。这样,在完成整个过程之前,主要的托管对象上下文不会受到影响。
这篇文章很棒,可以作为参考 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;
希望对您有所帮助。
首先,创建单例的更好(更安全)的方法是此处给出的示例: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;
}
接下来,由于您已经创建了一个必须停留几秒钟的托管 object 上下文,因此您必须在某处对它有一个强引用,而您确实这样做了。
如果您正在进行调试并质疑有关代码的一些基本假设,请为托管 object 上下文命名(或记录 MOC 指针的内存地址),您可以稍后在调试器中检查,以验证您确实在处理同一个调试器。
另请注意,如果您仅为此类导入创建了专用的托管 Object 上下文,则无需将其回滚。你可以直接丢弃它。
在我的应用程序中,我通常有一个 parent(root)管理的 object 上下文和几个 child 上下文;一个 child 用于主线程,另一个 child 用于导入类型操作。