2011-10-20 27 views
2

我目前的编码我的应用程序频繁加载图像(但不相同的图像)。据我测试,没有内存泄漏问题,但应用程序的内存使用量增加,因为我加载不同的图像。这意味着应用程序最终会在操作系统达到内存上限时被杀死。我通过仪器进行了检查,发现NSConcreteData拥有大量内存。iphone如何管理内存的时候经常加载图像

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]; 

当视图被解雇,所有分配的回忆得到的回报堆,它似乎像的应用程序增加内存 我分配了的NSData保持在内存里,因此,内存使用情况相比之前它加载图像。我不确定这是否是正常行为。 或者在不同的线程之间传递分配的内存是不好的做法?

回答

2

这可能或可能不会帮助您的确切情况,但这通常会通过密切关注您的autorelease堆栈增长而减少。你应该能够通过在自动释放池块中包装那些重创造者(来自url的数据,包含数据的图像)来减少这个问题。

@autoreleasepool { work with large NSObjects here } 

,或者根据不同的系统,你必须部署:

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

如果你可以使用@autoreleasepool,这样做。它稍微好一点,因为它直接与底层的autorelease栈进行交互。如果您需要向后兼容,请使用NSAutoreleasePool。在更高层次上,他们真正起到相同的作用,因为您应该能够在程序中交换其实现,而不会引入新问题。因此,在决定使用哪个操作系统时,它确实归结为您所定位的最小操作系统以及您为项目指定的构建设置。

你应该换你的处理和大(或多个)分配的创作自动释放块,因为自动释放的对象发送释放消息“在将来的某个时候”。通过显式创建和销毁autorelease池(并且通过使用autorelease的频率较低),可以让许多这些对象快速销毁。

至于为什么除了在您的程序中不使用autorelease之外,为什么这样做还不错:客户端和系统库最终会将大/多个图像/ NSData添加到autorelease池。自动释放池是像(线程局部)堆栈 - 当你摧毁当地的游泳池,而做你的游泳池是在上面所有的自动释放的消息将会实现,而自动释放对象将收到释放消息。

或者是不好的做法,通过不同的线程之间分配的内存?

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

+0

显式声明NSAutoreleasePool和只使用变量autoreleasepool之间的区别? – REALFREE

+0

@REALFREE评论/响应扩大并移到更新的答案。 – justin

1

尝试这样的事情。自动释放不如明确释放。

//on background thread data's retain count will now be 1 
NSData *data = [[NSData alloc] initWithContentsOfURL:url]; 


//on main thread (I'm assuming .image is a retained property) 
UIImage *newImage = [[UIImage alloc] initWithData:data]; 
imgView.image = newImage; 
[data release]; 
[newImage release]; 
0

尝试打开分配来计算内存, ,当每次你想释放的东西, 使它成为第一,确保没有人使用这个变量。 否则,它会崩溃。

在释放之前使变量等于零。