gpt4 book ai didi

iphone - Grand Central Dispatch (GCD) 与 CoreData

转载 作者:行者123 更新时间:2023-12-03 18:18:34 25 4
gpt4 key购买 nike

我在应用程序中使用 Grand Central Dispatch (GCD) 来完成一些繁重的工作。该应用程序使用 Core-Data 进行数据存储。这是我的场景(以及相关问题):

dispatch_queue_t main_queue = dispatch_get_main_queue();
dispatch_queue_t request_queue = dispatch_queue_create("com.app.request", NULL);

dispatch_async(request_queue, ^{
MyNSManagedObject *mObject = [self.fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];

// …
// <heavy lifting>
// …

// …
// <update mObject>
// …

[self saveManagedObjectContext];
});

由于 [self saveManagedObjectContext]fetchResultsController 委托(delegate)方法会自动调用。因此,UI 更新逻辑启动。

现在我的问题是,我需要使用 main_queue 来实现 -saveManagedObjectContext 吗?我应该对 main_queue 中的 NSManagedObject 执行所有操作吗?某些更新 NSManagedObject 的操作可能需要 2-3 秒。请指教。

最佳答案

涉及核心数据时有一条黄金法则 - 每个线程一个托管对象上下文。托管对象上下文不是线程安全的,因此如果您在后台任务中执行工作,您可以使用主线程来避免与 UI 操作的线程冲突,或者创建一个新的上下文来执行该工作。几秒钟后,您应该执行后者以阻止您的 UI 锁定。

为此,您需要创建一个新上下文,并为其提供与主上下文相同的持久存储:

NSManagedObjectContext *backgroundContext = [[[NSManagedObjectContext alloc] init] autorelease];
[backgroundContext setPersistentStoreCoordinator:[mainContext persistentStoreCoordinator]];

执行您需要执行的任何操作,然后在保存新上下文时,您需要处理保存通知,并使用 mergeChangesFromContextDidSaveNotification: 消息将更改合并到主上下文中。代码应如下所示:

/* Save notification handler for the background context */
- (void)backgroundContextDidSave:(NSNotification *)notification {
/* Make sure we're on the main thread when updating the main context */
if (![NSThread isMainThread]) {
[self performSelectorOnMainThread:@selector(backgroundContextDidSave:)
withObject:notification
waitUntilDone:NO];
return;
}

/* merge in the changes to the main context */
[self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
}

/* ... */

/* Save the background context and handle the save notification */
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(backgroundContextDidSave:)
name:NSManagedObjectContextDidSaveNotification
object:backgroundContext];

[backgroundContext save:NULL];

[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSManagedObjectContextDidSaveNotification
object:syncContext];

处理保存通知和合并非常重要,否则您的主 UI/上下文将看不到您所做的更改。通过合并,您的主 fetchResultsController 等将获取更改事件并按照您的预期更新您的 UI。

另一个需要注意的重要事项是 NSManagedObject 实例只能在从中获取它们的上下文中使用。如果您的操作需要对对象的引用,那么您必须将该对象的 objectID 传递给该操作,并使用 existingObjectWithID: 从新上下文中重新获取 NSManagedObject 实例。所以类似:

/* This can only be used in operations on the main context */
MyNSManagedObject *objectInMainContext =
[self.fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];

/* This can now be used in your background context */
MyNSManagedObject *objectInBackgroundContext =
(MyNSManagedObject *) [backgroundContext existingObjectWithID:[objectInMainContext objectID]];

关于iphone - Grand Central Dispatch (GCD) 与 CoreData,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4264540/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com