创建自动释放池并在不同的上下文中耗尽它
在视图控制器中,我有一个 UIImageView 作为子视图。在 willRotateToInterfaceOrientation 上,我将其替换为不同的 UIImageView。如果两者同时在内存中,有时会因为图像太大而崩溃。所以我想确保在创建新的之前完全释放第一个。当我对它调用removeFromSuperview时,我认为它基本上会在稍后的某个时刻自动释放,但我需要立即释放它。
因此,在创建 UIImageView 时,我似乎需要自己的自动释放池,然后在removeFromSuperview 调用之后调用 willRotateToInterfaceOrientation 时耗尽它。但文档说:
自动释放池应该总是在相同的上下文中被耗尽(例如 作为方法或函数的调用,或循环体) 它被创建了。自动释放池是“内联”使用的。那里 通常不应该成为您应该创建自动释放池的理由 对象的实例变量。
那么做到这一点的“正确”方法是什么?
In a view controller I have a UIImageView as a subview. On willRotateToInterfaceOrientation, i replace it with a different UIImageView. If both are in memory at the same time, it sometimes jettison crashes because the images are very big. So i want to make sure I completely dealloc the first one before making the new one. When i call removeFromSuperview on it, I think it is basically autoreleasing at some point later, but I need it to be dealloced immediately.
So it seems i need my own autorelease pool when the UIImageView is created, and then drain it when willRotateToInterfaceOrientation gets called, after the removeFromSuperview call. But the documentation says:
An autorelease pool should always be drained in the same context (such
as the invocation of a method or function, or the body of a loop) in
which it was created. Autorelease pools are used “inline.” There
should typically be no reason why you should make an autorelease pool
an instance variable of an object.
So what is the "right" way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
最好的办法就是优化你的图像。必须在同一上下文中分配和耗尽自动释放池。您应该做的第一件事是尝试减小图像的大小。如果它们是 png,请尝试
pngcrush
。如果图像仍然太大,请考虑使用mmap
一次加载图像的一部分。性能调整
The best thing to do is optimize your images. It is imperative that an autorelease pool is allocated and drained within the same context. First thing you should is try to reduce the size of the image. If they are png's try
pngcrush
. If the images are still to large consider usingmmap
to load portions of the image at a time.Performance Tuning
将自动释放池视为线程本地堆栈。您不会跨上下文或其他自动释放池进行持久化——弄乱顺序。将自动释放池用作 ivar 通常是一个错误。从多个线程使用自动释放池也是一个错误。
在您需要的每个地方创建一个,然后在该上下文中的该线程上销毁,而不会弄乱顺序,这样就可以了。这可能意味着在您提到的每种方法中创建和销毁一个。它们的创建和破坏速度相当快。
如果您需要在该上下文之外保留对另一个对象(例如您的图像)的引用,以确保它在您需要时存在,请这样做。
Think of autorelease pools as thread local stacks. You do not persist across contexts or other autorelease pools -- messing up the ordering. Having an autorelease pool as an ivar is often a mistake. Using an autorelease pool from multiple threads is also a mistake.
Create one every place you need it, and destroy in that context, on that thread, without messing up the ordering, and you'll be fine. That may imply creating and destroying one in each method you mentioned. They are quite fast to create and destroy.
If you need to hold a reference to another object (e.g. your image) beyond that context to ensure it lives as long as you need it, do so.