gpt4 book ai didi

objective-c - 核心数据合并两个托管对象上下文

转载 作者:太空狗 更新时间:2023-10-30 03:12:18 25 4
gpt4 key购买 nike

我的 Cocoa/Application 在主线程上有一个托管对象上下文。当我需要更新我的数据时,我的程序将:

  1. 开始一个新话题
  2. 从服务器接收新数据
  3. 创建一个新的托管对象上下文
  4. 向主线程发送通知以合并两个上下文

这是在主线程上接收通知的函数

- (void)loadManagedObjectFromNotification:(NSNotification *)saveNotification
{
if ([NSThread isMainThread]) {
[self.managedObjectContext mergeChangesFromContextDidSaveNotification:saveNotification];
} else {
[self performSelectorOnMainThread:@selector(loadManagedObjectFromNotification:) withObject:saveNotification waitUntilDone:YES];
}
}

我没有收到任何错误。我的问题是合并结果,它实际上连接了两个上下文中的托管对象。

我的实体是一个非常简单的属性和关系列表。

也许合并需要一些说明,以便了解何时更新的托管对象不是新的,而是第一个的编辑版本。我想在某个地方我需要指定一种方法来明确地标识一个实体(例如,一个属性可以像一个 ID)和一个类似合并策略的东西(如果 2 个托管对象代表同一个对象,则取 lastModificationDate 的那个更多最近)。

我只需要了解如何正确合并 2 个上下文,以便为每个对象创建一个更新副本。

更新 1

现在问题对我来说很清楚了。2 context 有一个很大的区别:ObjectID。当主线程上的上下文使用持久存储协调器获取 ManagedObjects 时,第二个线程通过获取远程 URL 创建这些对象。即使对象具有相同的内容,它们也会有 2 个不同的 objectID。

我的对象已经有一个唯一的标识符,我可以使用 setObjectId 来设置这个值。 (Apple 文档说这不是一个好主意)。

最佳答案

为了正确合并上下文,您需要执行以下操作。首先,您不需要自己的通知。对上下文执行保存操作会自动将以下通知转发给已注册的观察者:

NSManagedObjectContextDidSaveNotification

因此,您需要做的就是:

1) 在你的主线程中,可能在viewDidLoad方法中,注册这个通知:

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

2) 在你的主线程中实现 contextDidSave: 方法如下:

- (void)contextDidSave:(NSNotification *)notification
{

SEL selector = @selector(mergeChangesFromContextDidSaveNotification:);
[managedObjectContext performSelectorOnMainThread:selector withObject:notification waitUntilDone:YES];

}

3) 在您的dealloc 方法中添加以下内容:

[[NSNotificationCenter defaultCenter] removeObserver:self];

4) 使用类似以下方法在您的其他线程中创建一个新的上下文:

- (NSManagedObjectContext*)createNewManagedObjectContext
{

NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
[moc setPersistentStoreCoordinator:[self persistentStoreCoordinator]];
[moc setUndoManager:nil];
return [moc autorelease];
}

5) 收到新数据后,处理这种情况的正确方法是使用托管对象 ID。由于托管对象 ID 是线程安全的,您可以将它们从主线程传递到另一个线程,然后使用 existingObjectWithID:error: 检索与特定 ID 关联的对象,更新它并保存上下文.现在合并将按您预期的方式运行。或者,如果您事先不知道线程之间必须传递哪些托管对象 ID,那么在您的另一个线程中,您只需使用谓词获取对象以检索与从服务器检索到的对象对应的对象,然后更新它们并保存上下文。

关于objective-c - 核心数据合并两个托管对象上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6959225/

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