UITableView的单元格加载通过SDWebImage下载的超大尺寸图片崩溃问题及解决方案
通过修改SDWebImage库对下载的超大尺寸图片进行尺寸压缩。
在线上app运行期间发现画廊页面上拉到一定位置崩溃问题,经过定位是在UITableView的单元格种的UIImageView *headImageV加载一个特定图片时崩溃,拿到图片的地址下载这个图片,发现这个png图片比正常的图片大,达到2兆。进一步定位,发现这个图片尺寸达到7441*10524。使用mageData = UIImagePNGRepresentation(image)进行图片转换后再保存,发现这个图片竟让达到惊人的313.3兆。及崩溃的主要原因是该图片远远超过了iPhone手机的可以支持的图片尺寸,而SDWebImage对这种超大尺寸的小图片文件没有进行尺寸压缩,导致手机有概率崩溃。
解决办法:
1.用pod install下载所有组件;
2.在Podfile文件指定下载固定的最新SDWebImage版本,如:pod ‘SDWebImage’,’4.2.3’;
3.把SDWebImageImageIOCoder.m文件的decodedImageWithData函数的UIImage *image = [[UIImage alloc] initWithData:data];修改为UIImage *image = [self compressImageWithData:data];//[[UIImage alloc] initWithData:data]。把SDWebImageGIFCoder.m文件的decodedImageWithData函数的animatedImage = [[UIImage alloc] initWithData:data];修改为animatedImage = [self compressImageWithData:data];//[[UIImage alloc] initWithData:data];。
增加新的图片尺寸压缩函数:
/**最大尺寸手机支持的最大宽度,单位:ps像素(不是物理像素)*/
static const long long maxIphoneScreenMaxSizeWidth = 1242; //现在是iphone x
/**最大尺寸手机支持的最大高度,单位:ps像素(不是物理像素)*/
static const long long maxIphoneScreenMaxSizeHeight = 2208; //现在是iphone x
-(UIImage *)compressImageWithData : (NSData *)data
{
UIImage *image = [UIImage imageWithData:data];
if((image.size.height <= maxIphoneScreenMaxSizeHeight) && (image.size.width <= maxIphoneScreenMaxSizeWidth))
{
return image;
}
if((maxIphoneScreenMaxSizeWidth == 0) || (maxIphoneScreenMaxSizeHeight == 0))
{
//防止除数为0而crash,理论上不该出现maxIphoneScreenMaxSizeHeight为0
return nil;
}
//iphonex 5.8英寸屏 1242x2208
float width = maxIphoneScreenMaxSizeWidth;
float height = image.size.height/(image.size.width/width);
if((image.size.width >= maxIphoneScreenMaxSizeWidth) && (image.size.height >= maxIphoneScreenMaxSizeHeight))
{
width = maxIphoneScreenMaxSizeWidth;
height = image.size.height/(image.size.width/width);
if(height > maxIphoneScreenMaxSizeHeight)
{
height = maxIphoneScreenMaxSizeHeight;
width = image.size.width/(image.size.height/height);
}
}
else if(image.size.width >= maxIphoneScreenMaxSizeWidth)
{
height = maxIphoneScreenMaxSizeHeight;
width = image.size.width/(image.size.height/height);
}
// 创建一个bitmap的context
// 并把它设置成为当前正在使用的context
UIGraphicsBeginImageContext(CGSizeMake(width, height));
[image drawInRect:CGRectMake(0, 0, width , height)];
// 从当前context中创建一个改变大小后的图片
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
// 使当前的context出堆栈
UIGraphicsEndImageContext();
return newImage;
}
修改后测试应用运行正常了。