2

はじめに、これは数日前に行われた問い合わせのフォローアップです: https ://stackoverflow.com/questions/2981803/iphone-app-crashes-when-merging-managed-object-contexts

短いバージョン:EXC_BAD_ACCESSがアプリをクラッシュさせ、ゾンビモードにより、FetchedResultsControllerに埋め込まれたフェッチリクエストに埋め込まれた述語が原因であることが明らかになりました。オブジェクト内のオブジェクトは、明示的なコマンドなしでどのように解放されますか?

ロングバージョン:アプリケーション構造プラットフォームビューコントローラー->ゲームビューコントローラー(プラットフォームの選択に基づく)->ゲームビューコントローラーの追加

プラットフォームビューで行がクリックされると、そのプラットフォームのゲームビューにインスタンス変数が設定され、Games FetchedResultsControllerが通常の方法でフェッチリクエストを作成します。

- (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)sectionが呼び出されるまでに、_predicateはゾンビになり、テーブルがそれ自体を更新しようとすると、最終的にアプリケーションがクラッシュします。

私は多かれ少なかれ混乱しています。フェッチされた結果コントローラーまたはその一部をリリースしていません。割り当てが解除されるのは述語だけです。何か案は?

編集:テストとして、この行をFetchedResultsControllerメソッドに追加しました。

[fetchedResultsController.fetchRequest.predicate retain];

そして今はクラッシュしませんが、それはパッチのようで、私がすべきことではありません。

4

1 に答える 1

7

predicate変数を解放するべきではありません。new述語を作成するためにalloc、、、、retainまたはcopy(これは「narc」ルールです)を呼び出さなかったため、責任を負いませんreleasing。そこからゾンビが生まれます。

于 2010-06-08T03:55:31.900 に答える