为什么我的核心数据对象不能在相同会话中创建的相关对象之间使用提取请求显示?

问题描述:

这是一个非常奇怪的情况,我在过去的几天里一直在努力解决。为什么我的核心数据对象不能在相同会话中创建的相关对象之间使用提取请求显示?

我有一个Card实体在Transaction实体上具有多对多关系。我还使用Magical Record去除管理我的数据存储的样板代码。发生在下列顺序

我的问题:

  1. 创建Card对象
  2. 然后在另一个视图
  3. 创建Transaction对象。当我检查与[card.transactions count]交易算我送1的大小
  4. 但是,如果我使用相同的上下文执行提取请求,则交易不在那里。我的谓词如下所示:

    NSPredicate * predicate = [NSPredicate predicateWithFormat:@“card ==%@ & & deleted == 0”,card];

所以从逻辑上说,我也许不保存保存上下文交易后,但奇怪的是,如果我退出程序,然后重新运行它,该交易是存在的。如果我创建卡片,则步骤1-4也可以完美地工作,退出应用程序,然后运行应用程序并添加事务。然后我的保存交易代码工作正常。

所以我的问题是,为什么我的对象不会显示在新创建的父对象上使用获取请求,其中“新创建”意味着它是在与子对象相同的会话中创建的。

我创建的卡代码如下所示:

GYCard *card = [GYCard MR_createInContext:[NSManagedObjectContext MR_defaultContext]]; 
[[NSManagedObjectContext MR_defaultContext] MR_save]; 

然后,当我保存交易我的代码如下所示:

NSManagedObjectContext *localContext = [NSManagedObjectContext MR_defaultContext]; 
NSNumber *transactionAmount = [self.numberFormatter numberFromString:self.transactionAmountLabel.text]; 
GYTransaction *transaction = [GYTransaction MR_createInContext:localContext]; 
transaction.amount = transactionAmount; 
transaction.deleted = [NSNumber numberWithBool:NO]; 
transaction.card = self.card; 
[localContext MR_save]; 

不工作的代码是这样的:

+ (int) countTransactions:(GYCard *) card { 
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"card == %@ && deleted == 0", card]; 
    return [GYTransaction MR_countOfEntitiesWithPredicate:predicate inContext:[NSManagedObjectContext MR_defaultContext]]; 
} 

如果卡片是在同一个会话中创建的,countTransactions总是返回0。但如果我退出应用程序并重新启动,它就会100%运行。它也适用于在退出并重新启动应用程序后向卡添加任何新的事务。

这似乎是一个神奇的记录问题。我正在使用魔法记录的2.0 beta分支,并在恢复为标记版本后:1.8.3问题消失。所以2.0似乎是罪魁祸首。然而,知道2.0版为何导致这个问题仍然很有趣。

我强烈建议任何人使用魔法记录来避免2.0分支,直到它出来测试版。

更新:经过进一步调查,究竟是什么2。魔法记录的0测试版正在为1次保存生成2个保存通知,这导致我的应用程序无意中有2个版本的卡。这导致我登录的交易记录在第一张卡上,但第二张卡显然没有交易。我的提取请求然后获取第二张卡并返回零交易。退出并重新启动应用程序,然后让我的应用程序从数据存储中加载正确的事务,从而按预期工作。

这可能与NSFetchRequest上的includesPendingChanges财产有关。但是,默认值为YES,这意味着任何查询中都应包含任何未保存的更改。

我不知道什么MR_方法是引擎盖下做的,但setIncludesPendingChanges: documentation状态:

特别注意事项

YES的值与结果相结合,不支持键入 NSDictionaryResultType,包括计算聚合结果 (如max和min)。对于字典,从 获取返回的数组反映了持久存储中的当前状态,而不是 考虑了 上下文中的任何未决更改,插入或删除。

所以我会确保MR_countOfEntitiesWithPredicate方法没有做任何事情。也许可以尝试在您的环境中调用标准- (NSUInteger)countForFetchRequest:(NSFetchRequest *)request error: (NSError **)error方法并查看返回结果。

+0

嘿迈克。谢谢你的提示。神奇记录实际上是触发2个上下文保存通知。我正在使用这些通知来触发与Web服务的同步,结果是我无意中结束了每个创建的2个卡对象。然后提取请求获取错误卡的数据并以零事务结束。 –