大图(GIF)引发的CPU内存暴涨
起因:
在app首页有一个小的广告弹框,点击就弹出大图
由于每次点击都会去请求最新的GIF图,链接不间断的点击,导致手机发热严重,直至APP闪退。
在调试中监测到执行此操作时,CPU和内存一直在暴涨,CPU利用率达到200% 300% 内存也一直暴涨
后面定位到具体代码发现二进制转换成UIImage对象时,CPU利用率和内存使用很高,如果一直重复执行,它们就一直涨,直至手机发热,闪退。
解决方案:
减少二进制转换UIImage,由原本每次点击去执行sd_animatedGIFWithData 或者 animatedImageWithGIFData 操作改为
用一个UIImage变量来缓存gif图片对象,减少大文件的转换成本。
使用方法:
SDWebImage框架、FLAnimatedImage
sd_animatedGIFWithData 方法
animatedImageWithGIFData 方法
@property (nonatomic, strong) UIImage *bigImageView;
UIImageView * gifImageView = [[UIImageView alloc]init];
if (self.bigImageView){
gifImageView.image = self.bigImageView;
}else{
self.bigImageView = [UIImage sd_animatedGIFWithData:gifImageData];
gifImageView.image = self.bigImageView;
}
循环引用造成的CPU暴涨
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self){
self = [[[NSBundle mainBundle]loadNibNamed:@"TGSpellGroupDetailNavView" owner:self options:nil]lastObject];
}
[self up];
return self;
}
- (void)up{
[UIView animateWithDuration:0.6 animations:^{
self.shareButton.imageView.frame = CGRectMake(8, 4, 15, 13);
}];
[UIView animateWithDuration:0.6 delay:0.6 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.shareButton.imageView.frame = CGRectMake(8, 12, 15, 13);
} completion:^(BOOL finished) {
[self up];
}];
}
此功能是一个分享图标上下浮动的效果,由于存在循环调用,强强引用导致内存无法释放。造成了cpu的占用,导致UI卡顿。
修改为弱引用之后问题解决
__weak typeof (self) weakself = self;
- (void)up{
[UIView animateWithDuration:0.6 animations:^{
weakself.shareButton.imageView.frame = CGRectMake(8, 4, 15, 13);
}];
[UIView animateWithDuration:0.6 delay:0.6 options:UIViewAnimationOptionCurveEaseInOut animations:^{
weakself.shareButton.imageView.frame = CGRectMake(8, 12, 15, 13);
} completion:^(BOOL finished) {
[weakself up];
}];
}
注意!!!
如果类中使用了Block就要特别注意在Block内是否强引用了本类
观察控制器是否正常释放
- (void)dealloc
{
NSLog(@"%@ ============= delloc", NSStringFromClass([self class]));
}
-----代码1
_tableView.scrollViewDidScroll = ^(UIScrollView *scrollView) {
if (scrollView.contentOffset.y > self.view.height * 1.5) {
weakself.topBtn.hidden = NO;
} else {
weakself.topBtn.hidden = YES;
}
}
打印结果:无打印
-----代码2
_tableView.scrollViewDidScroll = ^(UIScrollView *scrollView) {
if (scrollView.contentOffset.y > KSCREENW * 1.5) {
weakself.topBtn.hidden = NO;
} else {
weakself.topBtn.hidden = YES;
}
}
打印结果:TGLandingPageViewController ============= delloc