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:
我有一个UITabBarController作为我的主基本视图控制器。在第一个选项卡下,我有一个UINavigationController,它当然有一个与之关联的rootViewController,称之为vcA。 vcA有一个按钮,可以使用以下代码触发子视图控制器vcB:
[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.
这似乎有效,我在仪器中看到vcB的新分配正在发生。当我将视图控制器弹回到vcA时,一切看起来都有效,但似乎vcB永远不会被释放(即,从不调用dealloc)。所以每次从vcA-> vcB-> vcA-> vcB开始,内存使用量都会增加和增加。
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
.
我在vcB中有一些实例变量,所有这些都在dealloc中设置为nil。但由于dealloc没有被解雇,所以它们实际上从未被设置为零。
I do have a [UIView animationWith...]
block which references the frame properties of self.view
, but I have managed that using the code:
我有一个[UIView animationWith ...]块,它引用了self.view的框架属性,但我已经使用代码管理了它:
__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?
有谁知道我怎么能找到仍然保留在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:
而我的dealloc(从未被解雇)是:
-(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.
更新:这实际上是由于子视图中的保留周期,并且与我首先想到的并不直接与视图控制器相关。 Dan F在这里引导我找到正确的答案,万一有人遇到类似的事情。
1 个解决方案
#1
1
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.
您的vcB应该完全取消分配,并在您弹回vcA时调用dealloc。你必须要么在某个地方保持对它的强烈引用,要么你的“流行”不正确。如果你用segue这样做,那可能是你的问题 - segues不应该用于倒退(除了展开segues)。因此要么使用unwind segue,要么使用popViewControllerAnimated返回vcA。此外,使用ARC时,无需在dealloc中将ivars设置为nil。
#1
1
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.
您的vcB应该完全取消分配,并在您弹回vcA时调用dealloc。你必须要么在某个地方保持对它的强烈引用,要么你的“流行”不正确。如果你用segue这样做,那可能是你的问题 - segues不应该用于倒退(除了展开segues)。因此要么使用unwind segue,要么使用popViewControllerAnimated返回vcA。此外,使用ARC时,无需在dealloc中将ivars设置为nil。