本文介绍了iOS-在ARC下弹出时未释放ViewController的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-07 01:44