Не могу выпустить NSFetchedResultsController в dealloc - PullRequest
0 голосов
/ 25 октября 2010

У меня есть два UITableViewControllers с довольно простым потоком пользовательского интерфейса. Один UITableViewController загружает другой UITableViewController при выборе элемента в первом UITableViewController.


(UITableViewController) Список историй -> Выбрать историю -> (UITableViewController) Список предложений


Во втором UITableViewController (MakeSentenceDetailViewController) я не могу выпустить свой NSFetchedResultsController, не вызвав ошибку (показывается с включенными зомби):

- [NSFetchRequest release]: сообщение отправлено освобожденному экземпляру 0x5b370f0

Счетчик сохранения NSFetchedResultsController остается равным 1, но когда я пытаюсь освободить его в dealloc, я получаю сбой.

Код, особенно в отношении NSFetchedResultsController, одинаков в обоих табличных представлениях, но в MakeSentenceDetailViewController я не могу выпустить этот NSFetchedResults Controller со сбоем - что дает мне утечку.

Как можно безопасно выпустить мой NSFetchedResultsController? Почему он хорошо работает в родительском (первом) tableviewcontroller - но не во втором?

Я могу предоставить код для первого UITableViewController, но в отношении NSFetchedResultsController он объявлен и используется почти таким же образом.

MakeSentenceTableViewController.h:

@interface MakeSentenceTableViewController : UITableViewController {
NSManagedObjectContext  *managedObjectContext;  
NSFetchedResultsController *fetchedResultsController;
}
@property (nonatomic, retain)  Story *story;
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
@end

MakeSentenceTableViewController.m (соответствующий код с NSFetchedResultsController):

 - (void)viewDidLoad {
 [super viewDidLoad];
 if (managedObjectContext == nil) 
 { 
 managedObjectContext = [(MyAppAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
 NSLog(@"After managedObjectContext: %@",  managedObjectContext);
 }
   NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
  NSEntityDescription *entity = [NSEntityDescription entityForName:@"Sentence" inManagedObjectContext:managedObjectContext];
  [request setEntity:entity];
  //sorting stuff:
  NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"order" ascending: YES];
  NSArray *sortDescriptors = [[NSArray alloc] initWithObjects: sortDescriptor, nil];
  [request setSortDescriptors:sortDescriptors];
  //[request setFetchBatchSize:FETCH_BATCH_SIZE];
  [sortDescriptors release];
  [sortDescriptor release];
  fetchedResultsController = [[NSFetchedResultsController alloc] 
    initWithFetchRequest:request managedObjectContext:managedObjectContext 
    sectionNameKeyPath:nil cacheName:nil];
  [request release];
  NSError *error;
  [fetchedResultsController performFetch:&error];
  NSLog(@"FetchedResultsController: %@", fetchedResultsController);
  NSLog(@"fetchedResultsController RetainCount at viewDidLoad: %d", [fetchedResultsController retainCount]);
 }

 - (void)dealloc {

  //Gotta figure out why I can't release this:
  [fetchedResultsController release]; //Crash! Burn! 
  NSLog(@"fetchedResultsController RetainCount at dealloc: %d", [fetchedResultsController retainCount]);
  [managedObjectContext release];
  [super dealloc];
 }

Ответы [ 2 ]

0 голосов
/ 25 октября 2010

Вы перевыпускаете NSFetchRequest

Вы автоматически выпускаете его здесь:

   NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];

, затем отпускаете его позже:

  [request release];

затем позже, когда вы отпускаетеfetchedResultsController, он пытается освободить тот же запрос снова.

0 голосов
/ 25 октября 2010
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
// ...snip...
[request release];

Вы отпускаете объект, владельцем которого вы отказались (с -autorelease).Вы не получите сообщение об ошибке в другом выпуске, потому что NSFetchedResultsController также сохраняет запрос на выборку;таким образом, контроллер действительно вызывает сбой, когда освобождает последнюю ссылку на запрос выборки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...