我正在使用NSFetchedResultsController管理在具有一个部分的表视图中显示已提取的托管对象。该表开始为空,用户可以使用UI向其添加新实体。目前,程序在添加第一个实体时始终有效,并且在添加第二个实体时始终崩溃。崩溃时有时没有出现错误,有时会出现不同类型的错误(下面包括一些错误)。通过日志语句和跟踪,我看到程序在NSFetchResultsController的委托的controllerWillChangeContent(调用[self.tableView beginUpdates];)方法之后崩溃,但在我的代码中的任何其他方法被调用之前。 以下是我的代码中的一些相关部分。配置NSFetchedResultsController:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Beer"
inManagedObjectContext:self.managedObjectContext]];
// Configure request's entity and predicate
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[sortDescriptor release];
[sortDescriptors release];
NSString *expression = [NSString stringWithFormat:@"brewery.name LIKE \"%@\"", self.brewery.name];
NSPredicate *predicate = [NSPredicate predicateWithFormat:expression];
[fetchRequest setPredicate:predicate];
self.resultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
self.resultsController.delegate = self;
[fetchRequest release];
NSError *error = nil;
BOOL success = [resultsController performFetch:&error];
if (!success) {
NSLog(@"Error fetching request %@", [error localizedDescription]);
}
添加新实体:
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Beer" inManagedObjectContext:self.managedObjectContext];
Beer *beer = [[Beer alloc] initWithEntity:entity insertIntoManagedObjectContext:self.managedObjectContext];
beer.name = beerName;
beer.brewery = self.brewery;
我已经在文档中看到了有关显示包含一个部分的表的问题的警告,并且我使用Apple的解决方法无效。无论如何,这些方法都不会在崩溃之前被调用。
我收到的一些错误:
Serious application error. Exception was caught during Core Data change processing: *** -[NSCFString compareObject:toObject:]: unrecognized selector sent to instance 0x4e808c0 with userInfo (null)
Serious application error. Exception was caught during Core Data change processing: *** -[CALayer compareObject:toObject:]: unrecognized selector sent to instance 0x4e53b80 with userInfo (null)
Serious application error. Exception was caught during Core Data change processing: *** -[UITextTapRecognizer controllerWillChangeContent:]: unrecognized selector sent to instance 0x4ca5d70 with userInfo (null)
Serious application error. Exception was caught during Core Data change processing: *** -[CALayer controllerWillChangeContent:]: unrecognized selector sent to instance 0x4e271a0 with userInfo (null)
Serious application error. Exception was caught during Core Data change processing: *** -[NSCFNumber countByEnumeratingWithState:objects:count:]: unrecognized selector sent to instance 0x4c96ee0 with userInfo (null)
正如您所看到的,即使没有对代码进行任何更改,错误(呈现错误时)也不一致。
有人能弄明白我做错了吗?
答案 0 :(得分:4)
您的不一致错误指向可能的过度释放问题。特别是因为更改您的代表只是重新加载数据会使问题消失。就个人而言,我会花时间来解决问题,而不是围绕它编码,因为你肯定会在那里出现代码问题,可能会在其他地方出现。
我会做以下事情:
objc_exception_throw
发生异常时,查看内存地址,查看正在访问的内容和位置。这将隔离问题并告诉您发生了什么。如果这不能揭示问题,那么发布你的NSFetchedResultsController
委托方法也是有帮助的,这样我就可以看出它们中是否有任何异常。
最好使用其他信息更新原始问题。
答案 1 :(得分:1)
您创建新实体的代码非常奇怪。怎么用呢:
Beer* beer = [NSEntityDescription insertNewObjectForEntityForName: @"Beer"
inManagedObjectContext: self.managedObjectContext];
beer.name = @"Grolsch";
此外,您没有致电NSManagedObjectContext#save:
。但是,您可能正在使用现在显示的部分代码执行此操作吗?
答案 2 :(得分:1)
虽然我没有解决这个特殊的问题,但是我采用了一种稍微不同的方法来编写提供我想要的功能的类,并且没有引起问题。我仍在使用NSFetchedResultsController,但是我没有实现所有四个委托方法,而只是实现了controllerDidChangeContent:,它只调用了[tableView reloadData]。
如果您在XCode中使用Core Data进行存储创建新的基于导航的应用程序,那么这是RootViewController类中包含的实现。您可能会失去对表编辑动画的一些控制权,但它很多更简单,并且可以用于我的目的。
答案 3 :(得分:1)
我最近遇到了类似的错误 - 你的问题在于过度释放,尤其是:
[sortDescriptors release];
您可以从
获取sortDescriptors对象[NSArray arrayWithObjects:sortDescriptor, nil];
没有“alloc”,“copy”或“new”,所以它返回一个自动释放的对象。因为您提前发布它,所以有两个地方可以崩溃 - 当NSFetchRequest使用它时,以及它被池释放时。有关详细信息,请参阅apple的memory management guide。
答案 4 :(得分:0)
这是一个旧的,但为了其他人有相同问题的好处,我花了几个小时试图了解发生了什么,并最终发现我的排序描述符导致这些随机崩溃的问题。
错误消息各不相同,但主要与compareObject:toObject选择器相关,如下所示。
- [_ NSCFSet compareObject:toObject:]:发送到实例的无法识别的选择器 - [ _NSCFString compareObject:toObject:]无法识别的选择器发送到实例
我的建议是尝试从代码中删除所有排序描述符和谓词,然后逐个添加它们以找出问题所在。
祝你好运! ROG