代码之家  ›  专栏  ›  技术社区  ›  Don Jones

iOS UIViewController释放自身?

  •  1
  • Don Jones  · 技术社区  · 15 年前

    我的应用程序的主视图是视图A,它是一个选项卡控制器。其中一个选项卡特别设置为“加载视图B”。视图B在您单击按钮时,会显示视图C。视图C依次有一个按钮,按下该按钮时,会向其代理(视图B的视图控制器)发送消息,然后该代理会取消视图C。

    现在,我的理解是视图A总是引用视图B。是吗?

    顺序如下:

    1. 按下按钮显示视图C(模式)。
    2. 按下按钮关闭-视图C发送消息,视图B的控制器关闭。此时将显示视图B。
    3. 再重复步骤2-3两次。
    4. 视图B的视图控制器释放(我在dealloc中有一个NSLog,所以我知道这正在发生)。视图仍会显示。
    5. 按下按钮显示视图C,得到“EXC\u BAD\u ACCESS”,因为视图B的视图控制器已被释放,所以按钮的“click”消息无处可去。

    任何时候都不会出现内存警告-我已经输入了NSLog来确保它。视图A和视图B都是在Interface Builder中构造的,而不是在代码中,而且我所编写的代码中绝对没有调用视图B的dealloc方法的。

    这总是在三次重复之后发生。

        // create button
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake(column*100+24, row*80+10, 64, 64);
        [button setImage:thumb forState:UIControlStateNormal];
        [button addTarget:self 
                        action:@selector(buttonClicked:) 
            forControlEvents:UIControlEventTouchUpInside];
    

    所以按钮应该发送“buttonClicked”消息到视图B的视图控制器。前三次运行良好,视图控制器神秘释放后停止工作。

    视图B应该 取消分配,因为它是应用程序选项卡栏中显示的顶级视图。

    编辑 :有趣的琐事。我在视图B的viewDidLoad中添加了一个[self retain],这将增加对象的保留计数。它做到了:在获得EXC\u BAD\u访问之前,我现在可以执行上述过程四次。我运行的是NSZombiesEnabled,所以我知道是视图B的控制器被释放了。我只需要找出它的retain计数在哪里被递减,因为我实际上没有编写任何这样做的代码。

    1 回复  |  直到 11 年前
        1
  •  1
  •   TechZen    15 年前

    1. 在第三步中,当您关闭视图控制器C时,没有释放视图控制器C,而是意外地释放了B。需要一段时间才能显示错误,因为B上有多个来自其他对象的保留。但是,每次释放C时,都会减少释放计数,直到它达到零。
    2. 您在某个地方有一个定制的访问器,比如C的delegate属性,它在被访问时向B发送一个释放。模式与(1)相同。

    你也可以覆盖B release 方法在发布时进行日志记录(不要忘了调用super),它将向您显示发布发生的时间,这将使您了解发布发生的位置。