iOS - ViewController not being released when poppe

2019-07-01 15:53发布

I have aUITabBarController as my main base view controller. Under the first tab, I have a UINavigationController which of course has a rootViewController associated with it, call it vcA. vcA has a button which fires a child view controller, vcB using the code:

[self performSegueWithIdentifier:@"PlacesDetailsSegue" sender:senderDictionary];

This appears to work, and I see in instruments that new allocations for vcB are occurring. When I pop the view controller back to vcA, everything looks to work, but it appears that vcB is never released (i.e., dealloc is never called). So every time a go from vcA->vcB->vcA->vcB, the memory usage increases and increases.

I have some instance variables inside vcB, all of which I set to nil in dealloc. But since dealloc isn't being fired, they are never actually set to nil.

I do have a [UIView animationWith...] block which references the frame properties of self.view, but I have managed that using the code:

__unsafe_unretained BBCategoryViewController *weakSelf = self;

[UIView animateWithDuration:duration
    animations:^{
        [_feedTableView setFrame:CGRectMake(0, 
                         _navBar.frame.size.height,
                         weakSelf.view.frame.size.width, 
                         weakSelf.view.frame.size.height - kMenuBarHeight)
        ];

     }
     completion:nil];

Does anyone have any idea how I can go about finding out what objects are still being retained on a vcB pop?

For reference, my interface extension is:

@interface BBCategoryViewController () <UITableViewDataSource, UITableViewDelegate> {
    UITableView *_feedTableView;
    UIRefreshControl *_refreshControl;
    BBSearchBar *_searchBar;
    MKMapView *_mapView;
    BBNavigationBar *_navBar;
    NSString *_title;
    NSString *_categoryId;
    NSArray *_feedArray;
}
@end

and my dealloc (which is never fired) is:

-(void)dealloc {

    NSLog(@"Dealloc: BBCategoryViewController\n");
    _feedTableView = nil;
    _refreshControl = nil;
    _searchBar = nil;
    _mapView = nil;
    _navBar = nil;
    _feedArray = nil;

}

UPDATE: This was actually due to a retain cycle in a child view, and not directly related to the view controllers as I first thought. Dan F led me to the correct answer here, in case anyone runs across something similar.

1条回答
聊天终结者
2楼-- · 2019-07-01 16:08

Your vcB should absolutely be deallocated, and dealloc called when you pop back to vcA. You must either be keeping a strong reference to it somewhere, or you're doing your "pop" incorrectly. If you're doing that with a segue, that could be your problem -- segues should not be used for going backwards (except unwind segues). So either use an unwind segue or use popViewControllerAnimated to go back to vcA. Also, when using ARC, there's no need to set your ivars to nil in dealloc.

查看更多
登录 后发表回答