伤不起的imageNamed方法
前段时间开发的时候总是遇到莫名其妙的崩溃。最后终于找出来是什么鬼原因:
1 [UIImage imageNamed:];
缓存了过多的大图片导致内存用尽,最后崩溃。最后解决这个问题的方法如下:
首先只缓存减小了大小的图片,然后需要用到大图片时从直接读取不缓存。
不过很明显,这个方法不够好。几天以后应用还是无声无息的崩溃了。经过多次的检查,排除了其他代码
的内存泄露等问题。再看console,里面一堆系统内存警告,然后退出了后台进程知道应用挂了。
所以,很明显+imageNamed这个方法简直太诡异了。即使什么清空缓存什么的估计也不管用。
这并不是什么难题,如果你干脆放弃缓存的话,苹果的例子代码中有这么一个函数足可使用。函数的注释也说的很清楚。
- (UIImage *)tileForScale:(CGFloat)scale row:(int)row col:(int)col{
// we use "imageWithContentsOfFile:" instead of "imageNamed:" here because we don't want UIImage to cache our tiles
NSString *tileName = [NSString stringWithFormat:@"%@_%d_%d_%d", imageName, (int)(scale * 1000), col, row];
NSString *path = [[NSBundle mainBundle] pathForResource:tileName ofType:@"png"];
UIImage *image = [UIImage imageWithContentsOfFile:path];
return image;
}
// we use "imageWithContentsOfFile:" instead of "imageNamed:" here because we don't want UIImage to cache our tiles
NSString *tileName = [NSString stringWithFormat:@"%@_%d_%d_%d", imageName, (int)(scale * 1000), col, row];
NSString *path = [[NSBundle mainBundle] pathForResource:tileName ofType:@"png"];
UIImage *image = [UIImage imageWithContentsOfFile:path];
return image;
}
或者你非要缓存,比如我们的应用。可以用一个NSMutableDictionary来缓存图片。
1 - (UIImage*)thumbnailImage:(NSString*)fileName
2 {
3 UIImage *thumbnail = [thumbnailCache objectForKey:fileName
4 if (nil == thumbnail)
5 {
6 NSString *thumbnailFile = [NSString stringWithFormat:@"%@/thumbnails/%@.jpg", [[NSBundle mainBundle] resourcePath], fileName];
7 thumbnail = [UIImage imageWithContentsOfFile:thumbnailFile];
8 [thumbnailCache setObject:thumbnail forKey:fileName];
9 }
10 return thumbnail;
11 }
2 {
3 UIImage *thumbnail = [thumbnailCache objectForKey:fileName
4 if (nil == thumbnail)
5 {
6 NSString *thumbnailFile = [NSString stringWithFormat:@"%@/thumbnails/%@.jpg", [[NSBundle mainBundle] resourcePath], fileName];
7 thumbnail = [UIImage imageWithContentsOfFile:thumbnailFile];
8 [thumbnailCache setObject:thumbnail forKey:fileName];
9 }
10 return thumbnail;
11 }
如果遇到内存低的警告,只要
1 [thumbnailCache removeAllObjects];
所以,无论如何在有大量图片的情况下千万不要使用
1 [UIImage imageNamed];
欢迎加群互相学习,共同进步。QQ群:iOS: 58099570 | Android: 572064792 | Nodejs:329118122
做人要厚道,转载请注明出处!