ios - 后台加载核心数据

标签 ios objective-c core-data

所以我已经阅读了一段时间的堆栈,我意识到我需要制作一个后台核心数据 NSManagedObjectContext 因为我正在加载大量记录并且我不想锁定用户界面。

我所做的如下:

backgroundContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];

NSPersistentStoreCoordinator *store = [[self managedObjectContext] persistentStoreCoordinator];

[backgroundContext setPersistentStoreCoordinator:store];

在我的函数调用中我直接执行:

 self.flightsFRC = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                    managedObjectContext:backgroundContext
                                    sectionNameKeyPath:nil
                                    cacheName:@"FlightRecords"];

我的代码目前可以正常工作,但我觉得它在其他地方“不好”,我直接访问 FRC 而没有处理任何同步或任何事情,例如我在此处迭代获取结果 Controller 的地方。

FlightRecording *rec = [[[self flightsFRC] fetchedObjects] objectAtIndex:i];

我错过了什么吗?我应该以某种方式通过 NSManagedObjectID 加载记录吗?这似乎“太简单了”

最佳答案

您当前的 FRC 指向后台上下文。不要那样做。仅指向主线程上的上下文。

为了让您的 FRC 收到更改通知,您实际上需要将后台上下文合并到主线程上下文。您的 CoreData 堆栈对象需要在后台上下文保存时注册通知:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(contextDidSave:)
                                             name:NSManagedObjectContextDidSaveNotification
                                           object:nil];

由于通知可以从其他线程发布,我们需要检查何时触发以确保我们在主线程上。如果我们已经在那里,那么我们可以在 NSManagedObjectContext 上调用 mergeChangesFromContextDidSaveNotification API。

- (void)contextDidSave:(NSNotification *)notification {
    if (![NSThread isMainThread]) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self contextDidSave:notification];
        });
    } else {
        [self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
    }
}

由于当主上下文中的数据发生变化时,您的 FRC 正在监听变化,因此 FRC 将触发其回调,以便您可以在 tableview 或 collectionview 中插入/删除/修改记录。

编辑:

听起来您可能没有在后台线程上做任何更改,因为您没有使用后台上下文的 performBlock: 或专用队列来完成工作:

[backgroundContext performBlock:^{
    // Do your work

    NSError *error = nil;
    BOOL success = [backgroundContext save:&error];

    //  error handling
}];

关于ios - 后台加载核心数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22824583/

相关文章:

objective-c - 比较浮点值有多危险?

ios - AFNetworking 2 如何设置根据每个请求更新的 header

ios - 从 Objective-C block 中修改存储在实例变量中的信号量

iphone - 当手绕传感器移动时,接近传感器打开

ios - 只有图像的自定义导航栏后退按钮

iphone - 在 NSPredicate 中使用 NSDate

ios - 按下按钮后标题消失

ios - 在自己的应用程序/ View 中接收本地通知(或如何在 SwiftUI 中注册 UNUserNotificationCenterDelegate)

ios - 在核心数据中存储 NSDate (swift)

ios - 快速实现查询