iphone - ExecuteFetchRequest 间歇性地抛出具有相同参数的异常。 "not key value coding-compliant for the key"

标签 iphone core-data fetch key-value-coding

编辑感谢马特的帖子,我现在明白我不应该尝试将“started”作为数组访问。但是,如果是这样的话,我想知道为什么这段代码似乎在其他地方工作。在我看来,这应该是“一个或另一个”。它应该起作用,或者不应该起作用。

原创 我在代码的各个部分使用相同的获取请求来查找最新的游戏:

Game *lastGame = [[[CoreDataAccess managedObjectContext] fetchObjectsForEntityName:@"Game" withPredicate:@"started == started.@max"] anyObject];

“Game”是一个 NSManagedObject,“started”是一个日期属性。 'started' 在 awakeFromInsert 中为每个对象设置一次。此后就再也没有改变过。游戏永远不会直接实例化,但它具有三个子类。我尝试过让 Game 变得抽象和具体,但都对这个问题没有任何效果。

我正在使用 NSManagedObjectContext 类别来执行获取,如 cocoa with love 上所示 http://cocoawithlove.com/2008/03/core-data-one-line-fetch.html

我收到的错误如下:

Serious application error.  An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:.  [<__NSDate 0xebb1130> valueForUndefinedKey:]: this class is not key value coding-compliant for the key @max. with userInfo {
    NSTargetObjectUserInfoKey = "2010-11-06 11:16:53 GMT";
    NSUnknownUserInfoKey = "@max";
}

在我看来,谓词可能试图将 @max 应用于单个 NSDate,而不是所有游戏中的所有“开始”属性。但我不确定。我不太擅长谓词,我花了很多时间尝试和犯错才做出这个。不过,我不明白完全相同的获取如何在不同的地方出现错误。

提取不是 NSFetchedResultsController 的一部分,但我在收到错误的类中使用了 fetchedResultsController 。例如:

- (void)configureCell:(UITableViewCell*)cell atIndexPath:(NSIndexPath*)indexPath{
Game *game = [self.frc objectAtIndexPath:indexPath];
Game *lastGame = [[[CoreDataAccess managedObjectContext] fetchObjectsForEntityName:@"Game" withPredicate:@"started == started.@max"] anyObject]; // Sometimes we get past this line, sometimes we don't...

NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:@"EEE, MMM d, yyyy h:mm a"];

if (game != lastGame)
    cell.detailTextLabel.text = [format stringFromDate:game.started];
else
    cell.detailTextLabel.text = @"In Progress";
[format release];
...
}

还有这里:

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
    Game *lastGame = [[[CoreDataAccess managedObjectContext] fetchObjectsForEntityName:@"Game" withPredicate:@"started == started.@max"] anyObject];
    if (lastGame == [frc objectAtIndexPath:indexPath])
        return NO;
    return YES;
}

这种精确的获取会在多个地方执行多次,例如在启动时,但它只在一个类中崩溃。正如我所说,它是间歇性的,但似乎是在我创建新的游戏对象之后的某个时间。游戏是在一个选项卡中创建的,上面的代码来自显示历史记录的第二个选项卡。

我见过类似的错误 here 。在这种情况下,通过重新启动计算机解决了问题,最终让 XCode 意识到该属性已从模型中删除。我已经尝试过了,但仍然遇到这个问题。我还尝试删除并重新创建模型中的“started”属性。我还阅读了《核心数据故障排除指南》,但也无法在那里找到任何帮助。

最佳答案

谓词一次应用于一个源对象。如果您的源对象没有数组属性,则无法使用数组运算符。

在你的例子中,谓词说:

Look at a given "Game". If its own "started" property is equal to its own "started" property with the @max KVC array operator applied, then this predicate will be true.

这不是你想要的。在谓词中使用 KVC 数组运算符的唯一情况是对象上的属性数组。例如

获取“games.@max.homeTeamScore > 50”的每个“赛季”(即主队在一场比赛中得分超过 50 分的赛季)。这是可行的,因为“Season”上的“games”属性将是一个数组,因此 games.homeTeamScore 也将是一个数组。

但是,单个游戏的“started”属性不是数组。你要操作的数组实际上是所有游戏的数组,它不是游戏的属性。

访问所有游戏的数组的唯一扭曲方法是首先获取所有游戏的数组,然后在谓词外部应用数组运算符,然后在谓词内部仅应用相等测试。

即首先获取所有游戏,然后重新获取:

fetchObjectsForEntityName:@"Game" withPredicate:@"started == %@", [allGames valueForKey:@"@max.started"]

但这也不是明智之举。

最终,您尝试使用的正确方法来获取具有最新开始日期的游戏,无法使用单行获取方法来完成。

您需要创建该方法的变体,允许您在获取请求上设置 setSortDescriptors: (按“开始”降序排序),然后在获取请求上设置 setFetchLimit:1 以仅获取第一个结果。

关于iphone - ExecuteFetchRequest 间歇性地抛出具有相同参数的异常。 "not key value coding-compliant for the key",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4113061/

相关文章:

iphone - 优化圆角性能

ios - 调整 TableView 单元格高度会影响最后一个单元格时的尾随空单元格

iphone - 数据模型中或 NSManagedObject 的自定义子类中定义的 transient 属性之间有区别吗?

javascript - 为什么没有定义 AbortController?

javascript - contact.map 不是一个函数

iphone - 是否可以向 iPhone 设置包添加信息或帮助文本?

IOS8 UIscrollview 内部 uiview 问题

ios - 核心数据迁移很慢,虽然没有什么可迁移的

ios - 后台抓取导致应用程序卡住而不是前台抓取

php - MySQL/PHP;仅从数据库中获取没有行的属性字段