1

这是一个非常奇怪的情况,我在过去几天一直在努力解决。

我有一个Card实体与实体上的多对多关系Transaction。我还使用 Magical Record 来删除围绕管理我的数据存储的样板代码。

我的问题按以下顺序发生:

  1. 创建一个Card对象
  2. Transaction然后在另一个视图中创建一个对象
  3. 当我检查交易计数时,[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% 工作。它还适用于在退出并重新启动应用程序后向卡添加任何新交易。

4

2 回答 2

2

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

我强烈建议任何使用 Magical Record 的人避免使用 2.0 分支,直到它完成测试版。

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

于 2012-05-10T11:43:48.330 回答
0

这可能与 上的includesPendingChanges属性有关NSFetchRequest。但是,默认情况下YES这意味着任何未保存的更改都应包含在任何查询中。

我不确定这些MR_方法在幕后做了什么,但setIncludesPendingChanges:文档指出:

特别注意事项

不支持 YES 值与结果类型 NSDictionaryResultType 一起使用,包括聚合结果的计算(例如 max 和 min)。对于字典,从 fetch 返回的数组反映了持久存储中的当前状态,并且不考虑上下文中的任何未决更改、插入或删除。

所以我会确保该MR_countOfEntitiesWithPredicate方法没有做任何时髦的事情。也许尝试在您的上下文中调用标准- (NSUInteger)countForFetchRequest:(NSFetchRequest *)request error: (NSError **)error方法并查看返回的内容。

于 2012-05-10T11:57:25.267 回答