Joh*_*her 8 cocoa ipc core-data
背景
我已经发布了一个关于在进程之间共享Core Data存储的基础知识的问题.
我正在尝试实施给出的建议,但我遇到了问题.
我的目标
我有两个过程 - 帮助应用程序和UI.它们共享一个数据存储.当Helper App将新数据保存到商店时,我希望UI更新它的NSManagedObjectContext.
当前的计划流程
Helper App Process将数据写入Store.
在Helper App中,我监听NSManagedObjectContextDidSaveNotification通知.
保存上下文后,我使用它们的URI表示和NSArchiver对插入,删除和更新的对象进行编码.
我将NSNotification发送到NSDistributedNotificationCenter,并将此编码字典作为userInfo发送.
UI进程正在侦听保存通知.收到通知后,它会使用NSUnarchiver取消归档userInfo.
它从给定的URI中查找所有更新/插入/删除的对象,并用NSManagedObjects替换它们.
它使用更新/插入/删除的对象构造NSNotification.
我在UI进程的托管对象上下文中调用mergeChangesFromContextDidSaveNotification:传入我在上一步中构建的NSNotification.
问题
插入的对象出现在UI管理对象上下文中,并且它们出现在UI中.问题来自更新的对象.他们只是不更新.
我试过的
最明显的尝试是将Helper App流程中的保存通知传递给UI流程.容易,对吗?好吧,不.分布式通知将不允许我这样做,因为userInfo字典的格式不正确.这就是我正在做所有NSArchiving的原因.
我已经尝试调用要更新的NSManagedObjects上的refreshObject:mergeChanges:YES,但这似乎没有任何效果.
我已经尝试在主线程和当前线程上执行mergeChangesFromContextDidSaveNotification:selector.似乎都没有影响结果.
我尝试过使用mergeChangesFromContextDidSaveNotification:在线程之间,这当然要简单得多,而且效果很好.但我需要在进程之间使用相同的功能.
备择方案?
我在这里错过了什么吗?我一直觉得我做的比现在要复杂得多,但是经过多次阅读文档并花了几天时间,我看不出任何其他方式来刷新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];
}
}
Run Code Online (Sandbox Code Playgroud)
UI代码
-(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];
}
Run Code Online (Sandbox Code Playgroud)
我相信您正在寻找 - (void)refreshObject:(NSManagedObject *)object mergeChanges:(BOOL)flag 。
这将使用持久存储中的信息刷新对象,并根据需要合并更改。
| 归档时间: |
|
| 查看次数: |
2358 次 |
| 最近记录: |