gpt4 book ai didi

cocoa - 如何使用 NSDistributedNotifications 在进程之间共享核心数据存储?

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

背景

我已经发布了一个有关 sharing a Core Data store between processes 基础知识的问题.

我正在尝试实现给出的建议,但遇到了问题。

我的目标

我有两个进程 - Helper App 和 UI。它们都共享一个数据存储。当助手应用程序将新数据保存到存储区时,我希望 UI 更新它的 NSManagedObjectContext。

当前程序流程

  1. 帮助应用程序进程将数据写入存储区。

  2. 在 Helper 应用程序中,我监听 NSManagedObjectContextDidSaveNotification 通知。

  3. 保存上下文时,我使用 URI 表示和 NSArchiver 对插入、删除和更新的对象进行编码。

  4. 我使用此编码字典作为 userInfo 向 NSDistributedNotificationCenter 发送 NSNotification。

  5. UI 进程正在监听保存通知。当它收到通知时,它使用 NSUnarchiver 取消归档 userInfo。

  6. 它从给定的 URI 中查找所有更新/插入/删除的对象,并将它们替换为 NSManagedObjects。

  7. 它使用更新/插入/删除的对象构造一个 NSNotification。

  8. 我在 UI Process 的托管对象上下文上调用 mergeChangesFromContextDidSaveNotification: ,传入我在上一步中构造的 NSNotification。

问题

插入的对象会正常进入 UI 托管对象上下文并出现在 UI 中。问题来自更新的对象。他们只是不更新​​。

我尝试过的

  1. 最明显要尝试的事情是是通过保存通知从 Helper App 进程到用户界面流程。容易,对吧?嗯,不。分布式通知不会让我以 userInfo 的身份执行此操作字典不在右边格式。这就是为什么我要做所有的事情NSArchiving 东西。

  2. 我已尝试调用刷新对象:合并更改:是要更新的 NSManagedObjects,但这似乎没有任何效果。

  3. 我尝试过执行mergeChangesFromContextDidSaveNotification:主线程上的选择器和当前线程。似乎两者都没有影响结果。

  4. 我尝试过使用mergeChangesFromContextDidSaveNotification:在线程之间之前,哪个类(class)简单得多并且有效完美。但我也需要这个进程之间的功能。

替代方案?

我在这里遗漏了什么吗?我一直有这样的感觉:我让这个变得比需要的更加复杂,但是在阅读了几次文档并花了几天时间研究这个之后,我看不到任何其他方式来刷新 MOC用户界面。

有更优雅的方法吗?或者我只是在代码中的某个地方犯了一个愚蠢的错误?

代码

我已尝试使其尽可能具有可读性,但仍然很困惑。抱歉。

帮助应用程序代码

   -(void)workerThreadObjectContextDidSave:(NSNotification *)saveNotification {
NSMutableDictionary *savedObjectsEncodedURIs = [NSMutableDictionary dictionary];
NSArray *savedObjectKeys = [[saveNotification userInfo] allKeys];

for(NSString *thisSavedObjectKey in savedObjectKeys) {
// This is the set of updated/inserted/deleted NSManagedObjects.
NSSet *thisSavedObjectSet = [[saveNotification userInfo] objectForKey:thisSavedObjectKey];
NSMutableSet *thisSavedObjectSetEncoded = [NSMutableSet set];

for(id thisSavedObject in [thisSavedObjectSet allObjects]) {
// Construct a set of URIs that will be encoded as NSData
NSURL *thisSavedObjectURI = [[(NSManagedObject *)thisSavedObject objectID] URIRepresentation];
[thisSavedObjectSetEncoded addObject:thisSavedObjectURI];
}
// Archive the set of URIs.
[savedObjectsEncodedURIs setObject:[NSArchiver archivedDataWithRootObject:thisSavedObjectSetEncoded] forKey:thisSavedObjectKey];
}

if ([[savedObjectsEncodedURIs allValues] count] > 0) {
// Tell UI process there are new objects that need merging into it's MOC
[[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"com.synapticmishap.lapsus.save" object:@"HelperApp" userInfo:(NSDictionary *)savedObjectsEncodedURIs];
}
}

用户界面代码

-(void)mergeSavesIntoMOC:(NSNotification *)notification {
NSDictionary *objectsToRefresh = [notification userInfo];
NSMutableDictionary *notificationUserInfo = [NSMutableDictionary dictionary];
NSArray *savedObjectKeys = [[notification userInfo] allKeys];

for(NSString *thisSavedObjectKey in savedObjectKeys) {
// Iterate through all the URIs in the decoded set. For each URI, get the NSManagedObject and add it to a set.
NSSet *thisSavedObjectSetDecoded = [NSUnarchiver unarchiveObjectWithData:[[notification userInfo] objectForKey:thisSavedObjectKey]];
NSMutableSet *savedManagedObjectSet = [NSMutableSet set];

for(NSURL *thisSavedObjectURI in thisSavedObjectSetDecoded) {
NSManagedObject *thisSavedManagedObject = [managedObjectContext objectWithID:[persistentStoreCoordinator managedObjectIDForURIRepresentation:thisSavedObjectURI]];
[savedManagedObjectSet addObject:thisSavedManagedObject];
// If the object is to be updated, refresh the object and merge in changes.
// This doesn't work!
if ([thisSavedObjectKey isEqualToString:NSUpdatedObjectsKey]) {
[managedObjectContext refreshObject:thisSavedManagedObject mergeChanges:YES];
[managedObjectContext save:nil];
}
}
[notificationUserInfo setObject:savedManagedObjectSet forKey:thisSavedObjectKey];
}
// Build a notification suitable for merging changes into MOC.
NSNotification *saveNotification = [NSNotification notificationWithName:@"" object:nil userInfo:(NSDictionary *)notificationUserInfo];
[managedObjectContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
withObject:saveNotification
waitUntilDone:YES];
}

最佳答案

我使用的方法

http://www.mlsite.net/blog/?p=518

然后每个对象都正确地出现故障,但故障是在缓存中获取的,因此仍然没有更新

我必须做[moc stalenessInterval = 0];

最终,通过关系,它发挥了作用。

关于cocoa - 如何使用 NSDistributedNotifications 在进程之间共享核心数据存储?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1815518/

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