最近的一个项目,有大量的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这种需要重用的控件就很需要它了。