我的UITableView中有若干UIButton,图片存放于本地硬盘,读取到内存后放进UIButton展示。
子线程负责从文件读入图片到内存,主线程用setImage:forState:展示。由于setImage:forState:耗时较长且在主线程,导致Table拖动起来较卡。代码如下(UIButton上的扩展):
- (void)asyncLoadImageAtPath:(NSString *)fullPath forState:(UIControlState)state { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ UIImage *image = [[UIImage alloc] initWithContentsOfFile:fullPath]; dispatch_async(dispatch_get_main_queue(), ^{ [self setImage:image forState:state]; }); }); }
后将setImage:forState:移入子线程,卡是不卡了,但是setImage:forState线程不安全,setImage:forState调用两秒后才会被显示。代码改为:
- (void)asyncLoadImageAtPath:(NSString *)fullPath forState:(UIControlState)state { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ UIImage *image = [[UIImage alloc] initWithContentsOfFile:fullPath]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ [self setImage:image forState:state]; }); }); }
QQ电影票中存于本地的大图拖起来不卡,且看起来是线程安全的。不知是怎么做的?
解决:最后读图重画成小尺寸一个线程,渲染一个线程,性能和自带的Photos差不多
最近从4s换回3GS,测试TavleView插图非常卡,于是测试了一下,发现initWithContentsOfFile并不是造成卡顿的主凶。因为这个动作本来就不在main queue里边的。而setImage必须是在main queue。于是写代码在本地生成一些更小的缩略图例如原本240px的直接缩放成80px,发现会快得多。
我的解决方法是:
1、写代码在http下载图片的complete block里面顺便把图片缩放成另外一个大小,另存一份。
2、cell for row代码:
把图片变小: