EXC_BAD_ACCESS - NSFetchedResultsController, UITableViewController, UINavigationController, UIPopoverController - PullRequest
1 голос
/ 11 января 2012

У меня есть UITableViewController внутри UINavigationController, внутри UIPopoverController.

UITableViewController использует NSFetchedResultsController. didSelectRowAtIndexPath помещает другой экземпляр моего UITableViewController с немного отличающимся предикатом в стек контроллера навигации.

Если я вставлю новый UITableViewController в стек, а затем вставлю его снова, я в конечном итоге получу EXC_BAD_ACCESS, если я попытаюсь сохранить объект, который обновил бы удаленное представление таблицы.

Как и ожидалось, установка делегата моего NSFetchedResultsController на nil удаляет ошибки EXC_BAD_ACCESS.

Я использую ARC. Так ясно, что эти объекты выпускаются. Хорошо. Но почему они все еще получают уведомление, когда есть изменение?

Код ниже. Я в основном отслеживаю историю просмотра веб-страниц в моей базе данных.

BookmarkViewController * bookmarkController = [[BookmarkViewController alloc] initWithStyle:UITableViewStylePlain andWebView:self.webView];
UINavigationController * bookmarkNavController = [[UINavigationController alloc] initWithRootViewController:bookmarkController];
self.bookmarkPopover = [[UIPopoverController alloc] initWithContentViewController:bookmarkNavController];
_bookmarkPopover.popoverContentSize = CGSizeMake(320, 44*10);
_bookmarkPopover.delegate = self;
bookmarkController.container=_bookmarkPopover;
bookmarkController.delegate=self;

BookmarkViewController использует NSFetchedResultsController, а BookmarkViewController - это delegate из NSFetchedResultsController.

- (NSFetchedResultsController *) myFetchedResultsController
{   
    if (self.fetchedResultsController != nil) {
        return self.fetchedResultsController;
    }   
    // Singleton
    CoreDataManager * dataManager = [CoreDataManager defaultDataManager];

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Bookmark" inManagedObjectContext:dataManager.managedObjectContext];
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"label" ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

    [fetchRequest setEntity:entity];
    [fetchRequest setPredicate:self.predicate];
    [fetchRequest setSortDescriptors:sortDescriptors]; 
    [fetchRequest setFetchBatchSize:20]; // Set the batch size to a suitable number.

    self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                                                    managedObjectContext:dataManager.managedObjectContext
                                                                      sectionNameKeyPath:@"type"
                                                                               cacheName:nil];
    self.fetchedResultsController.delegate = self;

    return self.fetchedResultsController;
}

А также у меня есть:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {    
    [self.tableView beginUpdates];
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    [self.tableView endUpdates];
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    BookmarkViewController * bookmarkViewController = [[BookmarkViewController alloc] initWithStyle:self.tableView.style 
                                                                                         andWebView:self.webview 
                                                                                          forFolder:bookmark.label];
    [self.navigationController pushViewController:bookmarkViewController animated:YES];
}

1 Ответ

0 голосов
/ 12 января 2012

Я нашел несколько связанных вопросов:

Нераспределенный контроллер представления, вызывающий EXC_BAD_ACCESS из-за полученных обновлений контроллера результатов

Если я выпускаю, я получаю плохой доступ, если я сохраняю, я пропускаю

2-я ссылка дала мне идею установить делегат равным nil в методе dealloc

-(void) dealloc
{
    self.fetchedResultsController.delegate = nil;
}

Но я использую ARC, поэтому я не могу вызвать [super dealloc] явно. Появляется, чтобы решить проблему, но я не уверен, что это правильно. Должен ли я также установить остальные мои локальные переменные на nil? Если это переопределит то, что когда-либо генерирует компилятор, произойдет ли утечка?

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