gpt4 book ai didi

iphone 频繁加载图片时如何管理内存

转载 作者:塔克拉玛干 更新时间:2023-11-02 10:18:10 25 4
gpt4 key购买 nike

我目前正在编写经常加载图像(但不是相同的图像)的应用程序。据我测试,没有内存泄漏问题,但随着我加载不同的图像,应用程序的内存使用量会增加。这意味着应用程序在达到内存上限时最终会被操作系统杀死。我通过仪器检查,发现 NSConcreteData 占用了大量内存。

memory allocation after the view is dismissed

//from different thread, and pass data to main thread
NSData *data = [[[NSData alloc] initWithContentsOfURL:url] autorelease];
//at main, data to uiimage
imgView.image = [[[UIImage alloc] initWithData:data] autorelease];

当 View 被关闭并且所有分配的内存都返回到堆时,似乎内存我为 NSData 分配了内存,因此与加载图像之前相比,应用程序的内存使用量增加了。我不确定这是否是正常行为。或者在不同线程之间传递分配的内存是不好的做法?

最佳答案

这对您的具体情况可能有帮助,也可能没有帮助,但是通过密切关注您的自动释放堆栈增长,通常可以减少这种情况。您应该能够通过将那些繁重的创建者(来自 url 的数据、带有数据的图像)包装在自动释放池 block 中来减少问题。

@autoreleasepool { work with large NSObjects here }

或者,根据您必须部署的系统:

NSAutoreleasePool * pool = [NSAutoreleasePool new];
work with large NSObjects here
[pool release];

如果你可以使用@autoreleasepool,那就去做吧。它稍微好一点,因为它直接与底层自动释放堆栈接口(interface)。如果您需要向后兼容,请使用 NSAutoreleasePool。在更高的层次上,它们实际上服务于相同的目的,从某种意义上说,您应该能够在不引入新问题的情况下在您的程序中互换它们的实现。因此,它实际上归结为您所针对的最低操作系统以及您在决定使用哪个时为项目指定的build设置。

您应该将大型(或许多)分配的处理和创建包装在自动释放 block 中,因为自动释放的对象会“在将来的某个时候”发送释放消息。通过显式创建和销毁该自动释放池(并减少使用自动释放池),您可以更快地销毁其中许多对象。

除了在您的程序中简单地不使用自动释放之外,为什么这会很好:客户端和系统库最终可能会将您的大/大量图像/NSData 添加到自动释放池中。自动释放池就像(线程本地)堆栈——当您销毁本地池时,所有那些在您的池位于顶部时发出的自动释放消息都将得到满足,并且自动释放的对象将收到它们的释放消息。

Or is it bad practice to pass allocated memory between different threads?

请记住,您应该从主线程向您的 UIKit 和 AppKit 对象发送消息。在 Cocoa 中,许多库可能会指定它们的线程模型。 NSData 遵循 Foundation 线程模型。这些对象不是显式线程安全的,但如果您在任何给定时间从不超过一个线程读取和/或写入,则它们可以安全使用(也就是说,只要您需要在 MT 上下文中使用它,就使用锁,或者通过复印件)。传递和共享数据/对象并不是一个坏习惯,有时这是必要的(或合乎逻辑的解决方案)。有一个小问题说它“还不错”:许多人对多线程和共享资源的理解不是很好(对许多人来说,这不是一项微不足道的技能)。

关于iphone 频繁加载图片时如何管理内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7831534/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com