Ios EXC_访问错误-NSFETCHEEDRESULTSCONTROLLER、UITableViewController、UINavigationController、UIPOPCOVERCONTROLLER

Ios EXC_访问错误-NSFETCHEEDRESULTSCONTROLLER、UITableViewController、UINavigationController、UIPOPCOVERCONTROLLER,ios,cocoa-touch,core-data,automatic-ref-counting,Ios,Cocoa Touch,Core Data,Automatic Ref Counting,我有一个UITableViewController在UINavigationController中,在UIPopoverController中 - (NSFetchedResultsController *) myFetchedResultsController { if (self.fetchedResultsController != nil) { return self.fetchedResultsController; } // Sin

我有一个
UITableViewController
UINavigationController
中,在
UIPopoverController

- (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;
}
UITableViewController
使用
NSFetchedResultsController
。didSelectRowAtIndexPath将另一个带有略微不同谓词的my
UITableViewController
实例推送到导航控制器堆栈上

如果我将一个新的
UITableViewController
推到堆栈上,然后再次弹出它,如果我试图保存一个会更新弹出的tableview的对象,我最终将获得一个
EXC\u BAD\u访问权

正如预期的那样,将my
NSFetchedResultsController的委托设置为
nil
将删除
EXC\u BAD\u访问
错误

我正在使用ARC。很明显,这些物体正在被释放。这没关系。但为什么他们在发生变化时仍会得到通知

代码如下。我基本上是在数据库中跟踪web视图的历史记录

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
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];
}

我发现了一些相关的问题:

第二个链接让我想到了在dealoc方法中将委托设置为nil

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

但我使用的是ARC,因此无法显式调用
[super dealloc]
。似乎可以解决问题,但我不确定这是否正确。我是否应该将其余局部变量设置为
nil
?如果这覆盖了编译器生成的内容,它会泄漏吗?

您不能显式调用
[super dealloc]
,因为您不再需要这样做。这一切都由你来处理。您不需要清空剩余的属性,但可以使用
-dealloc
清理使用此对象设置的任何观察者。