我怎么分享的一个核心数据储存进程之间使用NSDistributedNotifications?
题
背景
我已经发布的有关问题的基础知识 共享一个核心数据储存进程之间.
我正在尝试实施这些建议给予和我跑到的问题。
我的目标
我有两个进程--的辅助应用程序和用户界面。他们都共用一个单一的数据存储。我想要的用户界面来更新它的NSManagedObjectContext当的辅助应用程序有保存新数据。
目前的程序流程
辅助应用程序过程中写入数据的储存。
在辅助应用程序,我听NSManagedObjectContextDidSaveNotification通知。
在这方面,我编码插入、删除和更新对象使用其URI陈述和NSArchiver.
我送一个NSNotification的NSDistributedNotificationCenter与这一编码的字典如userInfo.
UI过程中是听于保存通知。当它接收通知时,它unarchives userInfo使用NSUnarchiver.
它看起来所有的更新/插入/删除的对象从Uri给予和取代他们与NSManagedObjects.
它构造一个NSNotification与更新插入/删除的对象。
我呼mergeChangesFromContextDidSaveNotification:在托管对象的上下文的过程,通过在NSNotification我构造的上一步。
的问题
插入的对象是错误的入UI托管对象的上下文的现他们出现在的用户界面。该问题与更新对象。他们只是不更新。
我已经试过了
最显而易见的事情试试会 应通过保存通知 从辅助应用程序过程中 UI过程。很简单,对不对?好,没有。分布式通知不会 请允许我这么做,因为userInfo 词典不是在正确的 格式。这就是为什么我做所有的 NSArchiving的东西。
我试着打电话给 refreshObject:mergeChanges:是上 该NSManagedObjects得到更新, 但是,这似乎没有任何 效果。
我已经试过执行 mergeChangesFromContextDidSaveNotification:选择的主线和 当前线。似乎既没有 影响结果。
我已经试过使用 mergeChangesFromContextDidSaveNotification:前线程之间,这的 当然是更简单和它的工作 完美。但我需要这个一样 功能之间的进程。
替代方案?
我失去了一些东西在这里?我一直有种感觉我在做这个复杂得多需要,但在阅读该文件多次和支出的几个固天在此,我看不到任何其他方式清凉商务部的用户界面。
是否有一个更优雅的方式这样做?或者我只是一个愚蠢的错误的地方,在我的代码?
代码
我试着让它尽量可读,但它仍然是一个烂摊子。对不起。
辅助应用程序的代码
-(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];
}
}
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];
}
解决方案
你要找的-(void)refreshObject:(十分整洁*)目mergeChanges:(BOOL)标志我相信。
这将刷新对象的信息,在永久性储存,合并的变化,如果你想要的。
其他提示
我用的方法
http://www.mlsite.net/blog/?p=518
然后每一对象是正确指责,但缺点是取的缓因此仍然没有更新
我不得不这样做 [交通部stalenessInterval=0];
它最后的工作,与关系。
我会去麦克的建议,只是看储存文件的变化。
虽然它可能不是效率最高的,我已经成功的使用 - [NSManagedObjectContext reset]
从第二个过程时,没有改变到一个商店。在我的情况的情况下,代码是相当直线—我要做的就是运行一个取的请求的一些数据之后,重新设置.我不知道这是如何将工作与绑定和复杂的用户界面,但是你可以发布一个通知,手工更新的东西,如果它不是自动处理的。
我不得不这完全相同的问题,一个应用程序的iPhone,我一直在工作。在我的情况下,方案参与设置的上下文的stalenessInterval到的东西,适当地极小(例如,用0.5秒)。
这个工作的,除了沙箱中的应用程序。你不能发送通知的用户信息词典。而不是考虑其他一些IPC喜欢弹性扩充或做。
在一个侧面说明,使用NSDustributedNotificationCenter并不总是100%,如果该系统是很忙。
设置stalenessInterval的管理对象方面的工作。我的情况下,涉及多个线程,而不是过程。