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.
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.