8

我有一个具有私有NSArray变量的视图控制器。变量在viewDidLoad方法中初始化。调用时会出现几个问题didReceiveMemoryWarning

  1. 我应该将私有变量设置为nil吗?
  2. 如果我将它设置为nil必须以什么方法重新创建它?视图控制器是否调用该viewDidLoad方法来重新创建它?

我问是因为视图的其他方法需要这个变量,如果它是nil.

谢谢!

4

5 回答 5

4

通常,您nil通过设置器(例如self.propertyName = nil)分配来卸载私有属性。或者您可以在调用 release 后将 ivar 设置为 nil,例如[_propertyName release]; _propertyName = nil;,但前者更可取。

didReceiveMemoryWarning当内存不足时调用该方法。它在每个视图控制器上调用,包括负责当前可见 UI 的控制器!

因此,您不能在接到调用时任意卸载数据didReceiveMemoryWarning——如果当前在显示器上可见,视图控制器可能需要该数据。

一般原则是didReceiveMemoryWarning可以摆脱任何可以帮助释放内存的资源,但仅限于那些不是立即需要的资源。例如,在 OpenGL 游戏中,您不会卸载当前在显示器上可见的纹理。但是,请参阅我的最后一段。

通常,您通过在需要它们时检查它们是否已加载来重新加载资源,如果没有,则加载它们。

不值得清理/释放微小的资源,例如单个正常大小的字符串。您应该专注于占用大量内存的项目。

幕后内存管理的最新进展意味着这些天您不太可能需要实际卸载数据 - 操作系统可以在幕后卸载和重新加载未压缩的图像数据等。

正如 Hot Licks 所提到的,模拟器有一个模拟内存警告的选项。值得在您的应用程序的各个点触发此内存警告以查看其行为方式。

于 2013-05-31T15:00:28.743 回答
1

创建延迟加载数据的自定义 getter。像这个片段这样的东西对非多线程环境有好处:

- (NSArray*) dataArray {
  if(_dataArray) return _dataArray;

  _dataArray = [self lordata];
  return _dataArray;
}

这样,如果您在内存警告中“释放”它们,数据总是会重新加载

于 2013-10-11T15:08:27.670 回答
0

ViewDidLoad方法仅在 ViewController 初始化时调用一次。如果你必须重新加载一些数据到你的 NSArray,你应该在需要的时候调用你自己的方法来做到这一点。

如果这个数组被代码的各个部分使用,也许你应该考虑重新设计你的代码结构,以避免数据大量集中在一个对象中。

编辑:正如@occulus 在下面的评论中指出的那样,在初始化视图时不会调用它,而是在视图被 ViewController 加载时调用它。我的错误

于 2013-05-31T10:12:39.733 回答
0

例如,我有一个应用程序将数据下载到一个很长的表视图(可能有 1000 条记录)。为了支持这一点,我实现了一个“稀疏”数组,允许在引用时在网络上“出错”的空元素(下载时表格单元格中有一个“正在下载”指示器)。

这是被操纵的,因此当 didReceiveMemoryWarning 发生时,阵列将被清除,使用最近最少使用的算法来删除阵列中最旧的 N%。恢复将是自动的——清空的单元格在被引用时会重新加载。

并不是说我推荐这个特定的方案,但请注意拥有大量数据的一般特征,有一种方法来“优先考虑”应该删除的内容,以及有一种“软”的方式来重新加载数据(理想情况下只重新加载那些在不久的将来需要)。

于 2013-05-31T19:40:09.377 回答
-2

最好将变量设置为零。我的意思是释放它所持有的内存didReceiveMemoryWarning并设置一个脏标志。

您始终可以检查数组 getter 中的脏标志(您可以自己编写)并重新填充它。这可能不是最好的方法。这完全取决于阵列的使用情况。

于 2013-05-31T10:19:45.460 回答