NSFetchedResultsController随NSInvalidArgumentException随机崩溃

时间:2011-09-05 18:50:49

标签: ios core-data crash nsfetchedresultscontroller

我有一个iOS应用程序,它使用Core Data将一些通过Internet下载的数据临时存储到数据库中。这些数据用于通过NSFetchedResultsController填充UITableView。这是生成控制器的代码(置于UIViewController中):

- (NSFetchedResultsController *)fetchedResultsController {

if (fetchedResultsController != nil) {
    return fetchedResultsController;
}

// Fetch results from database
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Order" inManagedObjectContext:[self.appDelegate ordersObjectContext]];
[fetchRequest setEntity:entity];

NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"patronName" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];

// Prefetch size: tweak this to improve performance
[fetchRequest setFetchBatchSize:20];

NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[self.appDelegate ordersObjectContext] sectionNameKeyPath:@"patronNameInitial" cacheName:nil];
self.fetchedResultsController = theFetchedResultsController;
fetchedResultsController.delegate = self;

[entity release];
[sort release];
[fetchRequest release];
[theFetchedResultsController release];

return fetchedResultsController;    

}

在我的应用程序工作流程中,包含此控制器的表视图必须多次卸载和加载,这就出现了问题。一旦上下文由我的“Order”实体填充,如果我使用结果控制器来回切换到视图,在从视图堆栈中多次推送和弹出后,应用程序崩溃并出现以下错误:

Fatal error. NSInvalidArgumentException. Entity name must not be nil.. User info: (null)

奇怪的是,对于控制器必须显示的给定数据集,每次应用程序运行时都会同时发生崩溃。示例:始终在第六次显示包含数据的视图。

但是如果我的对象上下文在同时没有改变的话,这怎么可能呢?为什么(例子)它第六次出现这个错误时会工作5次?

请注意,我的托管对象上下文和模型由我的应用程序委托拥有,并且永远不会卸载,因此如果我没有明确地修改它们,数据不应该随时间变化。

也许问题是因为我实际上并没有将“订单”保存到数据库中,而是将它们保存在内存中,在对象上下文中?我这样做是因为当应用程序停止时,必须擦除下载的数据。

编辑1:我试图在崩溃发生之前记录该行,

NSLog(@"%@", [[self.appDelegate managedObjectModel] entities]);

导致应用程序因EXC_BAD_ACCESS而崩溃,因此问题出现在managedObjectModel中。

编辑2:我尝试用超过1500个实体填充上下文,并且在加载和卸载视图30次后,我没有任何崩溃。只有当托管对象上下文只包含很少的实体时,我才会遇到崩溃!这太奇怪了。

2 个答案:

答案 0 :(得分:3)

你不应该发布实体

[entity release];

由于您从未在其上调用过alloc,因此您不拥有它。

答案 1 :(得分:0)

我注意到你没有缓存部分信息。为什么不 ?设置cacheName:@"Root"以使用NSFetchResultController的优势。 请注意,只有FetchRequestController的设置是不可变的,这才有意义。据我所知,在你发布的代码中,这就是你在这里所拥有的。所以你应该继续并缓存你的部分信息。您的数据只会在首次启动时加载到缓存中,只需稍加一些开销,但稍后只能观察表视图中的更改。

我试图想一想,如果这也可能是你的问题的原因,但只是模糊的假设我不确定,所以我会把它们留在这里。但是试着改变它......