iOS:关闭时视图控制器未释放

Posted

技术标签:

【中文标题】iOS:关闭时视图控制器未释放【英文标题】:iOS: View controllers are not releasing when dismissing 【发布时间】:2015-01-25 22:11:17 【问题描述】:

我正在像这样将当前控制器解散到我的根控制器。

  [navigationController popToRootViewControllerAnimated:YES];

但是,导航控制器中的所有视图控制器都没有被释放(我可以说是因为控制器类中的方法被调用了两次,并且没有调用 dealloc 方法)。我需要关于如何做才能弄清楚为什么会发生这种情况的建议。是否有我需要解除控制器的特定方法,或者可能正在发生其他事情。我正在使用 ARC。

【问题讨论】:

仪器告诉你什么? 当使用 ARC 时,它没有被授予,对象将被立即释放。您是否对其他地方的控制器有强烈的参考? 您在某处设置navigationController = nil; 吗?请发布所有引用 navigationController 变量的代码。 【参考方案1】:

除了持有对委托的强引用的可能性之外,您还应该检查使用视图控制器的任何块,并且在块内时始终使用对它的弱引用。

来自苹果docs:

假设您要发出一个 HTTP 请求,并在视图控制器的视图上显示您从服务器获取的一些用户信息。

- (void)requestUserInfo

     [self.client makeGETRequest:@"http://example.org/user/1/" usingBlock:^(User *user, NSError *error) 
          if (error) 
              [self.errorView displayWithError:error];
          
          else 
              self.userView.user = user;
              [self.userView setNeedsLayout];
          
     ];

在这种情况下,当用户厌倦了等待请求返回结果并点击“返回”按钮关闭页面时,视图控制器将不会被释放,直到请求完成加载并执行块。您可以通过覆盖 dealloc 自己查看。

因此,除非需要,否则请始终在块内使用 __weakself 的引用。

- (void)requestUserInfo

     __weak UIViewController *weakSelf = self;

     [self.client makeGETRequest:@"http://example.org/user/1/" usingBlock:^(User *user, NSError *error) 
          if (error) 
              [weakSelf.errorView displayWithError:error];
          
          else 
              weakSelf.userView.user = user;
              [weakSelf.userView setNeedsLayout];
          
     ];

【讨论】:

【参考方案2】:

这可能是由于许多原因,但您很可能持有指向您正在弹出的viewControllers 的强指针。发生的一种情况是,如果一个viewController 是一个delegate 到另一个viewController,并且delegate 属性是Strong,那么这两个viewControllers 保持一个强指针。

确保没有任何其他对象持有指向您正在弹出的viewControllers 的强指针。

【讨论】:

【参考方案3】:

您要弹出的控制器,它是从实际活动的viewController 中保留的。就这样。您有 2 个解决方案:

当您推送viewController 时,就地创建它:

UIViewController *vc = [UIViewController initWith...];
[navigationController pushViewController:vc animated:YES];

另一种解决方案是有一个weak 对其的引用:

//Property in the interface
@property (nonatomic, weak) UIViewController *vc;

//In the method
_vc = [UIViewController initWith...];
[navigationController pushViewController:vc animated:YES];

viewController 将被弹出,没有其他引用时,将被释放。

干杯!

【讨论】:

以上是关于iOS:关闭时视图控制器未释放的主要内容,如果未能解决你的问题,请参考以下文章

iOS 视图控制器未发布?

ARC 和dismissModalViewControllerAnimated:视图控制器内存未释放

添加 GameKit 后视图控制器未释放

在 iOS14 上释放 wkwebview 时,发送手势事件导致崩溃

在展示视图控制器被释放后,关闭展示的视图控制器

关闭模态视图控制器后自动释放崩溃