我怎么分享的一个核心数据储存进程之间使用NSDistributedNotifications?

StackOverflow https://stackoverflow.com/questions/1815518

  •  07-07-2019
  •  | 
  •  

背景

我已经发布的有关问题的基础知识 共享一个核心数据储存进程之间.

我正在尝试实施这些建议给予和我跑到的问题。

我的目标

我有两个进程--的辅助应用程序和用户界面。他们都共用一个单一的数据存储。我想要的用户界面来更新它的NSManagedObjectContext当的辅助应用程序有保存新数据。

目前的程序流程

  1. 辅助应用程序过程中写入数据的储存。

  2. 在辅助应用程序,我听NSManagedObjectContextDidSaveNotification通知。

  3. 在这方面,我编码插入、删除和更新对象使用其URI陈述和NSArchiver.

  4. 我送一个NSNotification的NSDistributedNotificationCenter与这一编码的字典如userInfo.

  5. UI过程中是听于保存通知。当它接收通知时,它unarchives userInfo使用NSUnarchiver.

  6. 它看起来所有的更新/插入/删除的对象从Uri给予和取代他们与NSManagedObjects.

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

  8. 我呼mergeChangesFromContextDidSaveNotification:在托管对象的上下文的过程,通过在NSNotification我构造的上一步。

的问题

插入的对象是错误的入UI托管对象的上下文的现他们出现在的用户界面。该问题与更新对象。他们只是不更新。

我已经试过了

  1. 最显而易见的事情试试会 应通过保存通知 从辅助应用程序过程中 UI过程。很简单,对不对?好,没有。分布式通知不会 请允许我这么做,因为userInfo 词典不是在正确的 格式。这就是为什么我做所有的 NSArchiving的东西。

  2. 我试着打电话给 refreshObject:mergeChanges:是上 该NSManagedObjects得到更新, 但是,这似乎没有任何 效果。

  3. 我已经试过执行 mergeChangesFromContextDidSaveNotification:选择的主线和 当前线。似乎既没有 影响结果。

  4. 我已经试过使用 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的管理对象方面的工作。我的情况下,涉及多个线程,而不是过程。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top