IOS UIImage 内存细节

最近的一个项目,有大量的scrollView+imageView,当iPad启动较多程序,再启动自己的这个程序的时候,就爆内存退出了~~

后来把所有的生成图片的方法,全部由imageNamed改成了imageWithContentsOfFile。

再运行,比之前好了不少,但是log还是会出现内存警告的信息,level 1,只是程序没有挂掉。

再在所有释放scrollView的子view的地方,把imageView.image设置为nil。

再运行,就没有警告log出现了~~

imageNamed是会把读取到的image存在某个缓存里面(我也不知道是哪个,但是它会。这样内存等于多用了一份~),第二次读取相同图片的话系统就会直接从那个缓存中获取(更快?),从某种意义上好像一种优化……但是imageNamed读取到的那个图片似乎不会因为Memory Warning而释放,所以用这个会导致在内存不足的时候闪退。imageWithContentsOfFile则是一个比较直接的读取,不会被存进某缓存,第二次读取相同图片也就是重新读取一遍。但是imageWithContentsOfFile读取的图片在Memory Warning的时候就会被释放,然后只有当前在用的那几个会被重新读取,所以节约了内存~
和imageView.image = nil无关
有关系的是 imageNamed这个方法是会缓存UIImage的 (即使相关的imageView已经析构) 

摘录一段:
对于大图片,慎用imageNamed这种方法来返回UIImage。

       理由是通过这个方法得到的UIImage是一直缓存在内存中,直到程序结束为止——这和我原先以为的系统会做一个引用计数,如果在引用计数为0的情况下自动清除该块内存的想法不一致。而且值得一提的是所有用IB在xib文件内设置图像的方法都是调用imageNamed这个方法,也就是说:这些内存在程序结束之前是一直保留着的,对于某些比较吃内存的应用就需要好好规划一下了。不过UITableViewCell这种需要重用的控件就很需要它了。

请告诉我正确的方式ALLOC一个UIImage到内存中,并释放它的iphone -

Using Instruments, I keep on getting pointed to a memory leak with a UIImage.我一直在使用仪器,越来越指出,一个UIImage内存泄漏。 
I think I'm assigning and releasing the memory correctly.我想我分配和释放内存正确。The leaked object in instruments is described as NSConcreteData泄漏的对象文书中被描述为NSConcreteData

Is the following the correct way to assign and release a UIImage?按照正确的方式来分配和释放一个UIImage?

UIImage* flagimg = [UIImage imageWithData: [NSData dataWithContentsOfURL:url2]]; [flagimg release]; flagimg =nil; 
 

  • [UIImage imageWithData:] returns an autoreleased object, which should not be released by you again. [UIImage imageWithData:]返回一个自动释放的对象,它不应该被释放,你再次。 So this code snipped contains not a memory leak but the opposite, a double free (in the worst case).所以这个代码片断的,包含不是内存泄漏,但相反,双重释放(在最坏的情况下)。

    Note that Instruments sometimes generates false positives and/or reports memory leaks in the Foundation itself (yep, they make mistakes too :-).需要注意的是仪器有时会产生假阳性和/或报告内存泄漏基金会本身(是的,他们会犯错误太:-)。

    The fastest way to alloc/release an object is to avoid convenience initializers (like imageWithData:) and instead to something like最快的方式是为了避免分配/释放一个对象方便的初始化(如imageWithData :)喜欢的东西,而

    推荐使用显示alloc 的方式使用对象。这样方便进行释放。因为隐式调用如“imageWithData”返回的是一个autorelease对象,它要等autoreleasePool池来进行释放。
    NSData* data = [[NSData alloc] initWithContentsOfURL:url]]; 
    UIImage* img = [[UIImage alloc] initWithData:data]; 
    [data release]; 
    // use your image 
    [img release];

    This will allocate and release your object right away and not wait until the autorelease pool is cleaned.这将分配和释放你的对象,而不是等到autorelease池清洗。

    But please note too, that a memory leak is generally not memory that is not yet freed, but that is lost and cannot be freed anymore , so an object which will be deallocated by the autorelease pool is not considered a memory leak.但也请注意,内存泄漏一般是没有尚未释放的内存,但丢失,不能再被释放 ,所以一个对象,该对象将被释放autorelease池不被认为是内存泄漏。

  • both imageWithData and dataWithContentsOfURL return autoreleased objects, so you should have no memory leaks in that code snippet. imageWithData和autoreleased对象dataWithContentsOfURL回报,所以你应该有没有内存泄漏的代码片段。

    Since flagimg is returned autoreleased, your [flagimg release]; call is not needed; you're over-releasing that object. ,由于flagimg返回自动释放,你的[flagimg release];不需要调用的,你是过度释放该对象。

  • as a general rule you can say作为一般规则,你可以说

    if you create an object an theres a "init","copy" or "retain" in it, you have to release it.如果你创建了一个对象,一个世界上的“初始化”,“复制”或“保留”中,你必须释放它。 if not, you get an autoreleased object.如果没有,你得到一个自动释放的对象。

    thats not always true, but in most cases那并不总是正确的,但在大多数情况下

原文地址:https://www.cnblogs.com/ygm900/p/2862623.html