子上下文未填充对默认上下文的更改(MagicalRecord)

ema*_*rbo 5 core-data nsmanagedobjectcontext ios magicalrecord magicalrecord-2.1

我试验了这里描述的相同问题.问题是使用DEFAULT上下文的子MOC来保存coredata,90%的时候,主线程上下文中的结果会更新来自子MOC的更改,但有时它们不是.

在我的测试中,我反复写入相同的实体(不是太快,使用UI):广告实体(favorite_count)和广告与用户之间的最爱关系.

从DEFAULT Context的子MOC保存时,这是MagicalRecord的预期输出(我也打印了updatedObjects计数):

[__52-[ZCServer postFavoriteAd:withDelegate:andSelector:]_block_invoke_2]? ? ? ? ? ? ? ? ? ? ? ? ? ?  POST FAVORITE  ? ? ? ? ? ? ? ? ? ? ? ? ? ?
2013-09-19 11:40:35.154  -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xb8b55e0) ? Saving <NSManagedObjectContext (0xb8b55e0): *** UNNAMED ***> on *** BACKGROUND THREAD ***
2013-09-19 11:40:35.155  -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xb8b55e0) ? Save Parents? 1
2013-09-19 11:40:35.155  -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xb8b55e0) ? Save Synchronously? 1
2013-09-19 11:40:35.155  -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xb8b55e0) ? Updated objects = 4
2013-09-19 11:40:35.183  -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xba72700) ? Saving <NSManagedObjectContext (0xba72700): *** DEFAULT ***> on *** BACKGROUND THREAD ***
2013-09-19 11:40:35.184  -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xba72700) ? Save Parents? 1
2013-09-19 11:40:35.184  -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xba72700) ? Save Synchronously? 1
2013-09-19 11:40:35.185  -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xba72700) ? Updated objects = 2
2013-09-19 11:40:35.188 -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xa3f7740) ? Saving <NSManagedObjectContext (0xa3f7740): *** BACKGROUND SAVING (ROOT) ***> on *** MAIN THREAD ***
2013-09-19 11:40:35.189 -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xa3f7740) ? Save Parents? 1
2013-09-19 11:40:35.189 -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xa3f7740) ? Save Synchronously? 1
2013-09-19 11:40:35.189 -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xa3f7740) ? Updated objects = 2
2013-09-19 11:40:35.191 __70-[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:]_block_invoke29(0xa3f7740) ? Finished saving: <NSManagedObjectContext (0xa3f7740): *** BACKGROUND SAVING (ROOT) ***> on *** MAIN THREAD ***
[__52-[ZCServer postFavoriteAd:withDelegate:andSelector:]_block_invoke672] ? ? ? ? ? ? ? ? ? ? ? ? ? ? ------*------ ? ? ? ? ? ? ? ? ? ? ? ? ? ?
Run Code Online (Sandbox Code Playgroud)

**注意:子MOC注册了4个更新,但在这种情况下,有两个对象(图像元数据)使用相同的信息更新.

但有时这是获得的输出(父项上没有updatedObjects):

[__52-[ZCServer postFavoriteAd:withDelegate:andSelector:]_block_invoke_2]? ? ? ? ? ? ? ? ? ? ? ? ? ?  POST FAVORITE  ? ? ? ? ? ? ? ? ? ? ? ? ? ?
2013-09-19 11:37:39.718  -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xb876d20) ? Saving <NSManagedObjectContext (0xb876d20): *** UNNAMED ***> on *** BACKGROUND THREAD ***
2013-09-19 11:37:39.718  -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xb876d20) ? Save Parents? 1
2013-09-19 11:37:39.719  -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xb876d20) ? Save Synchronously? 1
2013-09-19 11:37:39.719  -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xb876d20) ? Updated objects = 4
2013-09-19 11:37:39.720  -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xba72700) ? Saving <NSManagedObjectContext (0xba72700): *** DEFAULT ***> on *** BACKGROUND THREAD ***
2013-09-19 11:37:39.720  -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xba72700) ? Save Parents? 1
2013-09-19 11:37:39.720  -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xba72700) ? Save Synchronously? 1
2013-09-19 11:37:39.721  -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xba72700) ? Updated objects = 0
2013-09-19 11:37:39.722 -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xa3f7740) ? Saving <NSManagedObjectContext (0xa3f7740): *** BACKGROUND SAVING (ROOT) ***> on *** MAIN THREAD ***
2013-09-19 11:37:39.723 -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xa3f7740) ? Save Parents? 1
2013-09-19 11:37:39.723 -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xa3f7740) ? Save Synchronously? 1
2013-09-19 11:37:39.723 -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xa3f7740) ? Updated objects = 0
2013-09-19 11:37:39.725 __70-[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:]_block_invoke29(0xa3f7740) ? Finished saving: <NSManagedObjectContext (0xa3f7740): *** BACKGROUND SAVING (ROOT) ***> on *** MAIN THREAD ***
[__52-[ZCServer postFavoriteAd:withDelegate:andSelector:]_block_invoke672] ? ? ? ? ? ? ? ? ? ? ? ? ? ? ------*------ ? ? ? ? ? ? ? ? ? ? ? ? ? ?
Run Code Online (Sandbox Code Playgroud)

我使用串行队列对CoreData执行所有写操作.此串行队列为当前线程创建子MOC.这是作者的代码:

+ (void) saveWithBlock: (void(^)(NSManagedObjectContext *threadContext))block
{
    [ZCMagicalRecord saveWithBlock:block completion:nil];

}

+ (void) saveWithBlock: (void(^)(NSManagedObjectContext *threadContext))block completion:(MRSaveCompletionHandler)completion;
{
    dispatch_async( _queue, ^{

        NSManagedObjectContext *ctx = [NSManagedObjectContext MR_contextForCurrentThread];

        [ctx performBlockAndWait:^{
            block( ctx );

            [ctx  MR_saveWithOptions:MRSaveParentContexts|MRSaveSynchronously completion:completion];
        }];

    });
}
Run Code Online (Sandbox Code Playgroud)

另一方面,当我使用 [MagicalRecord saveUsingCurrentThreadContextWithBlock:]使用UI MainThread时,更改将全部填充到ROOT上下文和持久存储:

[__52-[ZCServer postFavoriteAd:withDelegate:andSelector:]_block_invoke_2]? ? ? ? ? ? ? ? ? ? ? ? ? ?  POST FAVORITE  ? ? ? ? ? ? ? ? ? ? ? ? ? ?
2013-09-19 11:47:01.082 -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xb348550) ? Saving <NSManagedObjectContext (0xb348550): *** DEFAULT ***> on *** MAIN THREAD ***
2013-09-19 11:47:01.082 -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xb348550) ? Save Parents? 1
2013-09-19 11:47:01.083 -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xb348550) ? Save Synchronously? 0
2013-09-19 11:47:01.083 -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xb348550) ? Updated objects = 5
2013-09-19 11:47:01.102 -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xa3cd840) ? Saving <NSManagedObjectContext (0xa3cd840): *** BACKGROUND SAVING (ROOT) ***> on *** MAIN THREAD ***
2013-09-19 11:47:01.102 -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xa3cd840) ? Save Parents? 1
2013-09-19 11:47:01.103 -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xa3cd840) ? Save Synchronously? 0
2013-09-19 11:47:01.103 -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xa3cd840) ? Updated objects = 2
2013-09-19 11:47:01.106  __70-[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:]_block_invoke29(0xa3cd840) ? Finished saving: <NSManagedObjectContext (0xa3cd840): *** BACKGROUND SAVING (ROOT) ***> on *** BACKGROUND THREAD ***
[__52-[ZCServer postFavoriteAd:withDelegate:andSelector:]_block_invoke676] ? ? ? ? ? ? ? ? ? ? ? ? ? ? ------*------ ? ? ? ? ? ? ? ? ? ? ? ? ? ?
Run Code Online (Sandbox Code Playgroud)

代码[MagicalRecord saveUsingCurrentThreadContextWithBlock:]与我写的相似(我只编写它以按顺序进行所有写入):

+ (void) saveUsingCurrentThreadContextWithBlockAndWait:(void (^)(NSManagedObjectContext *localContext))block;
{
    NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];

    [localContext performBlockAndWait:^{
        if (block) {
            block(localContext);
        }

        [localContext MR_saveWithOptions:MRSaveParentContexts|MRSaveSynchronously completion:nil];
    }];
}
Run Code Online (Sandbox Code Playgroud)

在我进行此测试时,CoreData中没有其他类型的写入.我在这里发布了POST FAVORITE示例,但DELETE FAVORITE是在帖子之间完成的,并且错误在帖子和删除中随机发生.服务器的响应也已正确验证.

注意

传递给代码块的对象上下文将被忽略.我总是使用[EntityClass MR_CreateEntity]它使用实际的线程上下文.并且在所有情况下使用MR_saveWithOptions:completion:的上下文是执行块的线程上下文.因此在所有操作中使用相同的上下文.该应用程序非常复杂,在大多数情况下工作正常,但这个错误可能会造成比我现在看不到的更多麻烦.