0

我有一个 iOS 应用程序,它从两个线程访问核心数据 sql 数据库。线程 A(主 UI 线程)更新核心数据记录,然后线程 B 尝试从线程 A 刚刚更新的实体集合中读取。麻烦的是,线程 B 没有“看到”线程 A 持续的变化。

线程 B 是通过将 NSOperation 子类对象添加到 NSOperationQueue 来创建的。NSOperation 子类的主要方法如下所示:

-(void) main {

    // NEED to create the MOC here and pass to the methods.
    NSManagedObjectContext* moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType];

    [moc setUndoManager:nil];

    [moc setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy]; // Had been working for months 

    [moc setPersistentStoreCoordinator:getApp().persistentStoreCoordinator];

    [self doTheWorkWithMOC:moc]; // Actually performs updates, using moc


    moc = nil;



}

稍后,线程 B 将其更改保存如下:

@try {
                // register for the moc save notification - this is so that other MOCs can be told to merge the changes
                [[NSNotificationCenter defaultCenter] 
                 addObserver:getApp() 
                 selector:@selector(handleDidSaveNotification:)
                 name:NSManagedObjectContextDidSaveNotification 
                 object:moc];

                NSError* error = nil;
                if ([moc save:&error] == YES)
                {
                    NSLog(@"%s SAVED FINE",__FUNCTION__);

                }else {
                    NSLog(@"%s NOT saved, error=%@ %@",__FUNCTION__,error,[error localizedDescription]);

                }

                // unregister from notification
                [[NSNotificationCenter defaultCenter] 
                 removeObserver:getApp() 
                 name:NSManagedObjectContextDidSaveNotification 
                 object:moc];





            }
            @catch (NSException * e) {
                NSLog(@"%s Exception: %@",__FUNCTION__, e);

            }

主 UI appdelegate 包含以下代码来处理保存通知:

- (void)handleDidSaveNotification:(NSNotification*) note 
{

    @try {

        // Notifications run on the same thread as the notification caller.
        // However, we need to ensure that any db merges run on the main ui thread.
        // Hence:
        [self performSelectorOnMainThread:@selector(mergeContexts:) withObject:note waitUntilDone:NO]; 


    }
    @catch (NSException * e) {
        NSLog(@"appDelegate handleDidSaveNotification Exception: %@", e);
    }

}
-(void)mergeContexts:(NSNotification*) note 
{
    if ([__managedObjectContext tryLock]==YES)
    {
        [__managedObjectContext mergeChangesFromContextDidSaveNotification:note];

        [__managedObjectContext unlock];
    }

}

大多数时候一切都很好。

但是,我有一台 iPad,当线程 A 读取数据库时,没有检测到线程 B 写入的更改。

任何人都可以在我的代码中看到任何会导致这种情况的东西吗?

非常感谢

4

1 回答 1

0

熟练工,

首先,您应该转而使用 iOS v5 和 Lion 中引入的基于队列的 MOC。这将使您的两个 MOC 更容易保持同步。您将不再需要使用锁定系统。

其次,一旦您移动到排队的 MOC,那么让它们保持同步以响应“已保存”通知是非常简单的。

第三,为什么你总是为保存通知添加和删除观察者?你不觉得这很可疑吗?显然,您错过了 MOC 之间的一些更新。

安德鲁

于 2012-11-23T13:32:41.650 回答