РЕДАКТИРОВАТЬ Благодаря посту Мэтта я теперь понимаю, что не должен пытаться получить доступ к «запущенному» как к массиву. Однако, если это так, я хотел бы знать, почему этот код работает в других местах. Мне все еще кажется, что это должно быть "один или другой". Это должно работать или не должно.
ORIGINAL
Я использую один и тот же запрос на выборку в различных частях моего кода, чтобы найти самую последнюю игру:
Game *lastGame = [[[CoreDataAccess managedObjectContext] fetchObjectsForEntityName:@"Game" withPredicate:@"started == started.@max"] anyObject];
'Игра' - это NSManagedObject, а 'запущено' - атрибут даты. 'start' устанавливается ровно один раз для каждого объекта в awakeFromInsert. Это никогда не меняется после этого. Игра никогда не создается напрямую, но имеет три подкласса. Я пытался сделать игру как абстрактной, так и конкретной, но ни одна из них не влияет на эту проблему.
Я использую категорию NSManagedObjectContext для выполнения выборки, как показано на какао с любовью здесь 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 вместо всех атрибутов «start» во всех играх. Я не уверен, хотя. Я не очень хорош с предикатами, и мне понадобилось много проб и ошибок, чтобы сделать это. Я не понимаю, как одна и та же выборка может иметь ошибки в разных местах.
Выборка не является частью 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;
}
Эта точная выборка выполняется несколько раз в нескольких местах, например, при запуске, но происходит сбой только в одном классе. Как я уже сказал, это периодически, но, кажется, это происходит через некоторое время после создания нового объекта Game. Игра создается на одной вкладке, а приведенный выше код взят со второй вкладки, которая отображает историю.
Я видел похожую ошибку здесь . В этом случае проблема была решена путем перезагрузки компьютера, что позволило XCode понять, что атрибут был удален из модели. Я попробовал это, и я все еще испытываю проблему. Я также попытался удалить и воссоздать атрибут «старт» в модели. Я также прочитал Руководство по устранению неполадок с основными данными, но не смог найти там никакой помощи.