iOS: 视图控制器在解雇时没有释放

iOS: View controllers are not releasing when dismissing

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

  [navigationController popToRootViewControllerAnimated:YES];

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

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

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

你弹出的控制器,它是从一个实际存在的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 弹出时,没有其他引用,将被释放。

干杯!

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

来自苹果 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];
          }
     }];
}

在这种情况下,当用户厌烦等待 return 结果请求并点击 "Back" 按钮关闭页面时,视图控制器将不会被释放,直到请求加载完成并执行块。您可以通过覆盖 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];
          }
     }];
}