创建自动释放池并在不同的上下文中将其耗尽

时间:2012-02-23 15:53:20

标签: objective-c memory-management autorelease

在视图控制器中,我有一个UIImageView作为子视图。在willRotateToInterfaceOrientation上,我用不同的UIImageView替换它。如果两者同时存在于内存中,它有时会因为图像非常大而导致崩溃。所以我想确保在制作新的之前完全取消第一个。当我在上面调用removeFromSuperview时,我认为它基本上会在某个时候自动释放,但是我需要立即释放它。

因此,在创建UIImageView时,我似乎需要自己的自动释放池,然后在removeFromSuperview调用之后调用willRotateToInterfaceOrientation时将其耗尽。但文件说:

  

自动释放池应始终在相同的上下文中排空(例如   作为方法或函数的调用,或循环的主体)   它是创建的。自动释放池使用“内联”   通常应该没有理由为什么你应该建立一个自动释放池   对象的实例变量。

这样做的“正确”方法是什么?

2 个答案:

答案 0 :(得分:2)

最好的办法是优化图像。必须在同一上下文中分配和排空自动释放池。首先应该尝试减小图像的大小。如果他们是png,请尝试pngcrush。如果图像仍然很大,请考虑使用mmap一次加载部分图像。

Performance Tuning

  

对资源施加大小限制。
当较小的资源文件执行时,避免加载大型资源文件。而不是使用高分辨率   图像,使用适合基于iOS的设备大小的图像。如果   您必须使用大型资源文件,找到仅加载该部分的方法   您在任何给定时间所需的文件。例如,而不是   将整个文件加载到内存中,使用mmap和munmap函数   将文件的一部分映射到内存中。欲获得更多信息   关于将文件映射到内存,请参阅文件系统性能   准则。

答案 1 :(得分:1)

将自动释放池视为线程本地堆栈。您不会在上下文或其他自动释放池中持久化 - 搞乱排序。将自动释放池作为ivar通常是一个错误。使用来自多个线程的自动释放池也是一个错误。

在你需要它的每个地方创建一个,并在那个上下文中,在那个线程上销毁,而不会弄乱订单,你会没事的。这可能意味着在你提到的每种方法中创建和销毁一个。他们创造和摧毁的速度非常快。

如果您需要在该上下文之外保留对另一个对象(例如您的图像)的引用,以确保它在您需要的时间内存在,请执行此操作。