【问题标题】:When is UIViewController viewDidUnload called?何时调用 UIViewController viewDidUnload?
【发布时间】:2010-11-20 03:11:01
【问题描述】:

注意:这个问题已经过时了——viewDidUnload 已弃用 iOS 6。

UIViewController 的 viewDidUnload 什么时候自动被调用?是的,我知道,当视图卸载时。但是什么时候会自动发生呢?我该如何手动完成?谢谢。

【问题讨论】:

  • 看起来不一定会被调用;无需先调用 viewDidUnload 即可释放 UIViewController。
  • 经过大量测试,我确实看到 viewDidUnload 有时可能不会被调用。我看到视图控制器在没有调用 viewDidUnload 的情况下被释放。
  • 这个问题应该被删除。 viewDidUnload 已弃用,在 iOS 6 中不再调用。
  • @RosePerrone 不是每个用户都有 iOS 6。
  • ViewDidUload 方法从 iOS 6 开始被弃用。

标签: iphone uiviewcontroller


【解决方案1】:

如果您在模拟器中发出内存警告(查看菜单),这将被任何附加到不可见视图的视图控制器调用。

这是因为默认情况下,视图控制器注册了内存警告通知,并且当前未使用的任何视图都将被视图控制器卸载 - viewDidUnload 方法在那里,以便您可以清理您想要的任何其他内容,节省额外的内存(或者如果您保留了一些 IBOutlets 来帮助释放内存,否则这些内存会被正在卸载的视图释放)。

通常,您在 dealloc 中释放的任何 IBOutlets,也应在此方法中释放(并将引用设置为 nil)。

【讨论】:

  • 它不会被我的应用程序调用,因为我一次只实例化一个视图控制器,当我第一次切换它们时,我释放(self.vc = nil)当前的一个(之后从 superview 中删除)。
  • 我不使用 IBOutlets,我不使用 IB。
  • 我很确定您是正确的,如果您一次只有一个 VC,那么视图将永远不会被卸载。最常见的情况是当您使用导航控制器时,您导航离开的视图仍然存在......即使您不使用 IB,如果您添加为相同规则保留引用的子视图也将适用 - 无参考(尽管这似乎不适用于您的情况)。
  • 是的,将属性设置为 nil 会用一块石头杀死两只鸟(释放和取消设置引用)。
  • @mk12 兄弟,不要讨厌 IB。我尽可能使用 NIB,因为它显着缩短了开发时间。更少的开发时间 = 更多的收入。此外,UI 设计师在您使用它时会爱上您(让您更有市场)。只是传递一些爱你的方式!
【解决方案2】:

除了在模拟器中手动发出内存警告外,您还可以通过编程方式发出一个

- (void)_simulateLowMemoryWarning {
  // Send out MemoryWarningNotification
  [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidReceiveMemoryWarningNotification
                                                      object:[UIApplication sharedApplication]];
  // Manually call applicationDidReceiveMemoryWarning
  [[[UIApplication sharedApplication] delegate] applicationDidReceiveMemoryWarning:[UIApplication sharedApplication]];
}

然后您可以使用计时器使其每 5 秒发生一次

static NSTimer *gLowMemoryTimer = nil;

- (void)stopLowMemoryTimer {
  [gLowMemoryTimer invalidate];
  gLowMemoryTimer = nil;
}

- (void)startLowMemoryTimer {
  if (gLowMemoryTimer) {
    [self _stopLowMemoryTimer];
  }
  gLowMemoryTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(_simulateLowMemoryWarning) userInfo:nil repeats:YES];
}

【讨论】:

  • 测试应用的绝妙想法。
  • 这是一个好主意,但由于这仅用于测试,因此最好使用 UIApplication 中的私有方法,该方法在发生实际内存警告时调用,以防万一做其他事情:[[UIApplication sharedApplication] performSelector:@selector(_performMemoryWarning)];
【解决方案3】:

每当 viewcontroller 的 view 属性设置为 nil 时,都会调用-viewDidUnload,无论是手动设置还是最常见的是通过didReceiveMemoryWarning:

【讨论】:

  • 我有一个场景,我希望 -viewDidUnload 在由 UIPopoverController 托管的 UIViewController 上触发。在弹出窗口被解除后,我手动取消了视图控制器的视图,但 -viewDidUnload 仍然没有被触发。有什么想法为什么不呢?
  • 您是否在 viewDidUnload 中设置了断点以确认它没有触发?确保将视图设置为 nil 的代码实际上引用了正确的视图控制器(检查视图控制器此时本身不是 nil,并且它的值与您期望的值相同)。此类问题的最常见原因是意外出现了不在屏幕上的额外视图控制器。
  • 是的,我确实有一个断点和一些使计时器无效的代码。断点从未被击中,我的计时器继续运行(正在将消息记录到控制台)。我还验证了我的 popover 的 contentViewController 是正确的,而不是 nil。想知道视图在技术上是否仍然可见。我在 -popoverControllerDidDismissPopover: 方法中取消了视图。
  • 所以你打电话给popoverController.contentViewController.view = nil,但[contentViewController viewDidUnload] 永远不会触发?这是令人惊讶的。如果“didDismiss”触发,则视图应该在屏幕外。我不知道一个明显的问题,但我会构建一个小型测试工具来调查通常会发生什么。
  • 是的,这正是我所做的。我最终将我想要运行的代码从 -viewDidUnload 移动到 -viewDidDisappear:animated
【解决方案4】:

iOS 6.x 及更高版本

我知道这是一个较老的问题,但我觉得应该提交关于 iOS 6 中 viewDidUnload API 更改的答案,即在 iOS 6 中 viewDidUnload 不再被调用(根本)并且已经已弃用。

【讨论】:

  • 进一步:如果您针对 iOS 5 进行部署,您仍应编写 viewDidUnload 实现,但重要的是不要有任何需要在 iOS 6 上运行的逻辑。
【解决方案5】:

viewDidUnload 在内存不足的情况下调用。我们应该卸载我们在 viewDidLoad 方法中加载的东西。我们需要通过调用访问器方法将其设置为 nil 来放弃对象的所有权。在出口的情况下,对象释放自身,因此可以将对象引用安全地设置为 nil。如果不是综合属性,那么我们首先需要释放对象而不是我们设置为 nil。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-18
    • 2012-04-18
    • 1970-01-01
    • 1970-01-01
    • 2011-03-12
    • 2012-06-25
    • 2012-09-12
    • 2011-01-22
    相关资源
    最近更新 更多