前言,这是几天前进行的调查的后续行动: https://stackoverflow.com/questions/2981803/iphone-app-crashes-when-merging-managed-object-contexts
简短版本:EXC_BAD_ACCESS正在崩溃我的应用程序,僵尸模式揭示了我的谓词嵌入在我的Fetched Results Controller中嵌入的获取请求中的罪魁祸首。如果没有明确的命令,对象中的对象如何被释放?
长版: 应用结构 平台视图控制器 - >游戏视图控制器(根据平台选择预测) - >添加游戏视图控制器
当在平台视图上单击一行时,它会在该平台的Games View中设置一个实例变量,然后Games Fetched Results Controller以正常方式构建一个获取请求:
- (NSFetchedResultsController *)fetchedResultsController{
if (fetchedResultsController != nil) {
return fetchedResultsController;
}
//build the fetch request for Games
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"Game"
inManagedObjectContext:context];
[request setEntity:entity];
//predicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"platform == %@",
selectedPlatform];
[request setPredicate:predicate];
//sort based on name
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name"
ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
//fetch and build fetched results controller
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc]
initWithFetchRequest:request
managedObjectContext:context
sectionNameKeyPath:nil
cacheName:@"Root"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
[sortDescriptor release];
[sortDescriptors release];
[predicate release];
[request release];
[aFetchedResultsController release];
return fetchedResultsController;
}
在此方法结束时,fetchedResultsController的_fetch_request - > _predicate成员设置为NSComparisonPredicate对象。一切都在世界各地。
到时候 - (NSInteger)tableView :( UITableView *)tableView numberOfRowsInSection :( NSInteger)部分被调用,_predicate现在是一个Zombie,当表试图更新自己时,它最终会崩溃应用程序。
我或多或少地陷入困境。我没有发布获取的结果控制器或它的任何部分,并且唯一获得dealloc'd的部分是谓词。有任何想法吗?
编辑: 作为测试,我将此行添加到Fetched Results Controller方法中:
[fetchedResultsController.fetchRequest.predicate retain];
现在它不会崩溃,但这似乎是一个补丁,而不是我应该做的事情。
答案 0 :(得分:7)
您不应该发布predicate
变量。您没有调用new
,alloc
,retain
或copy
(这是“narc”规则)来创建谓词,因此您不对{ {1}}它。这就是你的僵尸来自哪里。