问题描述
我有一个UITabBarController
作为我的主要基础视图控制器.在第一个选项卡下,我有一个UINavigationController
,当然还有一个与之关联的rootViewController
,将其称为vcA
. vcA
有一个按钮,该按钮会触发子视图控制器,vcB
使用以下代码:
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];
这似乎起作用,并且我在工具中看到vcB的新分配正在发生.当我将视图控制器弹出回vcA
时,一切看起来都可以正常工作,但是似乎vcB从未发布(即,从未调用过dealloc).因此,每次从vcA->vcB->vcA->vcB
开始访问时,内存使用量都会不断增加.
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
中有一些实例变量,所有这些变量都在dealloc
中设置为nil
.但是由于不会触发dealloc,因此它们实际上从未设置为nil
.
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
.
我确实有一个[UIView animationWith...]
块,该块引用了self.view
的帧属性,但是我已经使用以下代码对此进行了管理:
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];
有人知道我如何才能找出仍保留在vcB pop上的对象吗?
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
和我的dealloc(从未触发过)是:
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;
}
更新:这实际上是由于子视图中的保留周期所致,与我最初想到的视图控制器没有直接关系. Dan F引导我给出了正确的答案,以防有人碰到类似东西.
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.
推荐答案
您的vcB应该绝对被释放,并在弹出vcA时调用dealloc.您必须在某处保持对它的强烈引用,或者您在错误地执行"pop"操作.如果您使用segue来执行此操作,那可能就是您的问题-不应将segues用于倒退(unwind segues除外).因此,要么使用放松的搜索,要么使用popViewControllerAnimated返回vcA.另外,在使用ARC时,无需在dealloc中将ivars设置为nil.
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.
这篇关于iOS-在ARC下弹出时未释放ViewController的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!