我有一个具有私有NSArray
变量的视图控制器。变量在viewDidLoad
方法中初始化。调用didReceiveMemoryWarning
时会出现一些问题:
nil
吗?nil
,必须重新创建哪种方法?视图控制器是否调用viewDidLoad
方法来重新创建它?我问,因为视图的其他方法需要此变量,如果它是nil
则无法工作。
谢谢!
答案 0 :(得分:4)
通常,您可以通过设置器(例如nil
)分配self.propertyName = nil
来卸载私有属性。或者你可以在调用release之后将ivar设置为nil,例如[_propertyName release]; _propertyName = nil;
,但前者更可取。
当内存不足时调用didReceiveMemoryWarning
方法。它在每个视图控制器上调用,包括负责当前可见UI的一个(
因此,当您调用didReceiveMemoryWarning
时,您不能随意卸载数据 - 视图控制器可能需要该数据,如果它当前在显示器上可见。
一般原则是didReceiveMemoryWarning
可以摆脱它可以帮助释放内存的任何资源,但只有那些不是立即需要的资源。例如,在OpenGL游戏中,您不会卸载当前在显示器上可见的纹理。但是,请参阅我的最后一段。
通常,您需要在需要时检查它们是否已加载来重新加载资源,如果没有,则加载它们。
不值得利用/释放微小资源,例如单个正常大小的字符串。你应该专注于占用大量记忆的物品。
幕后内存管理的最新进展意味着您现在不太可能需要实际卸载数据 - 操作系统可以在后台卸载和重新加载未压缩的图像数据等。
正如Hot Licks所提到的,模拟器有一个模拟内存警告的选项。值得在应用程序的各个点触发此内存警告以查看其行为。
答案 1 :(得分:1)
创建懒惰加载数据的自定义getter。像这个片段这样的东西对于非多线程的解除是有益的:
- (NSArray*) dataArray {
if(_dataArray) return _dataArray;
_dataArray = [self lordata];
return _dataArray;
}
这样,如果您在内存警告中“释放”数据,则始终会重新加载数据
答案 2 :(得分:0)
初始化ViewController时,ViewDidLoad
方法只调用一次。如果必须将一些数据重新加载到NSArray,则应该在需要时调用自己的方法来执行此操作。
如果代码的各个部分使用了这个数组,那么你应该考虑重新设计你的代码结构,以避免仅在一个对象中集中大量数据。
编辑:正如@occulus在下面的评论中指出的那样,在View初始化时不会调用它,但是ViewController加载View时我的错误
答案 3 :(得分:0)
作为一个例子,我有一个应用程序将数据下载到一个非常长的表视图(可能是1000个记录)。为了支持这一点,我实现了一个“稀疏”数组,允许在引用时通过网络“故障”的空元素(在下载时在表格单元格中使用“下载”指示符)。
这是被操纵的,因此当didReceiveMemoryWarning发生时,将使用最近最少使用的算法清除数组,以删除最旧的N%数组。恢复将是自动的 - 清空的单元格在被引用时会重新加载。
不是我推荐这个特定的方案,而是注意拥有大量数据的一般特征,有一种方法可以“优先”应该删除的内容,并且有一种“软”方式来重新加载数据(理想情况下只重新加载在不久的将来需要的部分)。
答案 4 :(得分:-2)
最好将变量设置为nil。我的意思是释放它在didReceiveMemoryWarning
中保存的内存并设置脏标志。
您可以随时检查数组getter中的脏标志(您可以自己编写)并重新填充它。这可能不是最好的方式。这完全取决于阵列的用法。