iPhoneSE列表加载图片crash的解决方案

5 篇文章 0 订阅

        近期业务做了评论模块,评论内容跟其他APP基本一致,就是评分、文字以及图片,每条评论可以至多包含6张图片,在评论列表会展示评论星级、用户头像、昵称、评论文字、图片以及评论时间,逻辑非常简单,一天搞完,提交打包给测试验证,基本无有效bug,第二天下午测试跑过来说在iPhoneSE上有一个商品,点击后滑动就必会crash,我开始以为是图片数组越界导致,但是测试说别的手机不会crash,我去bugly查看crash信息,发现bugly空空如也,并无crash上报,无奈之下只有真机debug了,找到对应商品,点击进详情页然后滑动,果然crash了,但是xcode并未捕捉到crash堆栈,猜测是内存问题,于是在didreceivememeryWarning方法出断点,再次启动,重新操作,不出意外,crash了,但是还是未走到断点处,最后,打开所有的异常断点,再次启动测试,这次捕捉到了,是sdwebimage 代码在解压图片的时候内存申请失败,在console也出现了terminate due to memery issue,原因找到了怎么解决呢?于是开始以下尝试:

  1. 是否是SE内存太小,SD内存cache太多导致?于是设置SDCache最多为6张(一条评论数据的图片),然后重新启动,验证,依然crash。
  2. 是否是内存峰值过高导致?于是在每条cell更新的时候加上了autoreleasepool,接着启动,测试,crash继续。
  3. 是否是某张图片太大导致?于是把每张图片都download下来,查看图片大小,但是没有发现某张图片dataSize非常大,但总算有结果了,原来每张图片大小有500k,终端上传的时候做了500k的上限限制,于是想着裁剪图片。
  4. 最后网络上找到了WWDC针对大图片优化的最佳实践,就是下采样,主要代码如下
    CGImageSourceRef source =  CGImageSourceCreateWithURL((__bridge CFURLRef)url, nil);
                CFDictionaryRef options = (__bridge CFDictionaryRef) @{
                    (id) kCGImageSourceCreateThumbnailWithTransform : @YES,
                    (id) kCGImageSourceCreateThumbnailFromImageAlways : @YES,
                    (id) kCGImageSourceThumbnailMaxPixelSize : @(60*[UIScreen mainScreen].scale)
                };
                
                CGImageRef scaledImageRef = CGImageSourceCreateThumbnailAtIndex(source, 0, options);
                UIImage *scaled = [UIImage imageWithCGImage:scaledImageRef];
                CGImageRelease(scaledImageRef);

 创建缩略图以后,再次验证,crash问题没有了,但是出现了别的问题,cell滚动后重新加载会显示placeholder,然后再显示图片,这是没有加缓存的问题,于是,运用SDImagecache给缩略图加上缓存,再次运行,完美解决。最后附上代码

@interface ThumbImageManager : NSObject

+ (instancetype)sharedManager;
- (void)thumbImageWithUrl:(NSString *)urlString 
                    width:(float)width
                    block:(void(^)(NSString *url,UIImage *image))callBack;
@end
#import "ThumbImageManager.h"

@interface ThumbImageManager ()

@property(nonatomic,strong)NSOperationQueue *queue;

@end

@implementation ThumbImageManager

+ (instancetype)sharedManager{
    static ThumbImageManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[ThumbImageManager alloc] init];
    });
    return manager;
}
- (instancetype)init{
    self = [super init];
    if (self) {
        _queue = [[NSOperationQueue alloc] init];
        _queue.maxConcurrentOperationCount = 6;
    }
    return self;;
}
- (void)thumbImageWithUrl:(NSString *)urlString width:(float)width block:(void(^)(NSString *url,UIImage *image))callBack{
    
    NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
        
    NSString *path = [[urlString md5String] stringByAppendingString:@"thumb"];
      UIImage *image =  [[SDImageCache sharedImageCache] imageFromCacheForKey:path];
        if (image) {
            callBack(urlString,image);
        }else{
            NSURL *url = [NSURL URLWithString:urlString];
            CGImageSourceRef source =  CGImageSourceCreateWithURL((__bridge CFURLRef)url, nil);
            CFDictionaryRef options = (__bridge CFDictionaryRef) @{
                (id) kCGImageSourceCreateThumbnailWithTransform : @YES,
                (id) kCGImageSourceCreateThumbnailFromImageAlways : @YES,
                (id) kCGImageSourceThumbnailMaxPixelSize : @(width*[UIScreen mainScreen].scale)
            };
            
            CGImageRef scaledImageRef = CGImageSourceCreateThumbnailAtIndex(source, 0, options);
            UIImage *scaled = [UIImage imageWithCGImage:scaledImageRef];
            CGImageRelease(scaledImageRef);
            [[SDImageCache sharedImageCache] storeImage:scaled forKey:path completion:nil];
            callBack(urlString,scaled);
        }
        
    }];
    [_queue addOperation:op];
}
@end

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值