MagicalRecord saveInBackgroundWithBlock不保存对象

时间:2014-03-11 21:46:17

标签: ios core-data magicalrecord

这段代码对我很有用,即使我重新运行应用程序也会保存选项。

 Player *selectedPlayer = [_players objectAtIndex:indexPath.row];

    [MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext) {

        Option *option = [Option MR_createInContext:localContext];

        option.playerID = selectedPlayer.playerID;

        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"playerID == %@", selectedPlayer.playerID];

        Player *foundPlayer = [Player MR_findFirstWithPredicate:predicate inContext:localContext];

        [foundPlayer addOptionObject:option];

        [[STGameHelper sharedInstance].selectedGame addPlayersObject:selectedPlayer];

    } completion:^{

        if ([self.delegate respondsToSelector:@selector(didSelectedPlayer)])
        {
            [self.delegate didSelectedPlayer];
        }

    }];

但是如果尝试这个,数据库在重新运行应用程序后没有任何Option对象。

[MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext) {

    Option *option = [Option MR_createInContext:localContext];

    option.playerID = selectedPlayer.playerID;

    Player *selectedPlayer = [_players objectAtIndex:indexPath.row];

    [selectedPlayer addOptionObject:option];

    [[STGameHelper sharedInstance].selectedGame addPlayersObject:selectedPlayer];

} completion:^{

    if ([self.delegate respondsToSelector:@selector(didSelectedPlayer)])
    {
        [self.delegate didSelectedPlayer];
    }

}];

我想我在不同的环境中工作,但我不明白它是如何工作的。所以Player条目存储在数据库中没有任何问题。为什么我无法选择已保存的播放器记录并为此实体附加已在某些上下文中创建的新记录。

我想当我重新运行app并且数据库使用为Concert属性选择的内部规则(级联等)删除选项实体时,某些上下文会被扭曲。我是对的还是我困惑了?

1 个答案:

答案 0 :(得分:2)

我对MagicalRecord一无所知,但...... 你似乎在这里有一个交叉背景问题......

使用CoreData时,托管对象与其托管上下文紧密绑定 您无法链接来自2个不同上下文的对象。

在第二个代码段中,您将localContext中插入的对象(我认为是一个临时的私有队列上下文),您的选项,并将其链接到另一个上下文中的现有对象(可能是您的主要上下文)点。

您需要通过以下方式将selectedPlayer导入您的本地情境:

NSManagedObjectID* selectedPlayerID = [[_players objectAtIndex:indexPath.row] objectID];
NSError* error = nil;
Player* selectedPlayer = [localContext existingObjectWithID:selectedPlayerID error:&error];
//handle error if needed ...

这可以防止您的跨语境问题。

另一件事:

您的代码在后台执行,因此在执行时[_players objectAtIndex:...可能会发生变化。

您最好在声明块之前获取播放器对象ID,并在块中捕获该对象ID:

NSManagedObjectID* selectedPlayerID = [[_players objectAtIndex:indexPath.row] objectID;
[MagicalRecord saveInBackgroundWithBlock:^{/*your code here using selectedPlayerID*/}];