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

发布于 2025-01-08 11:23:38 字数 483 浏览 1 评论 0原文

在视图控制器中,我有一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

眉目亦如画i 2025-01-15 11:23:38

最好的办法就是优化你的图像。必须在同一上下文中分配和耗尽自动释放池。您应该做的第一件事是尝试减小图像的大小。如果它们是 png,请尝试 pngcrush。如果图像仍然太大,请考虑使用 mmap 一次加载图像的一部分。

性能调整

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

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 using mmap to load portions of the image at a time.

Performance Tuning

Impose size limits on resources.
Avoid loading a large resource file when a smaller one will do. Instead of using a high-resolution
image, use one that is appropriately sized for iOS-based devices. If
you must use large resource files, find ways to load only the portion
of the file that you need at any given time. For example, rather than
load the entire file into memory, use the mmap and munmap functions to
map portions of the file into and out of memory. For more information
about mapping files into memory, see File-System Performance
Guidelines.

指尖凝香 2025-01-15 11:23:38

将自动释放池视为线程本地堆栈。您不会跨上下文或其他自动释放池进行持久化——弄乱顺序。将自动释放池用作 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文