ios内存优化

大图(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

代码1 页面没有正常的释放,说明存在内存泄露

代码2 说明页面正常释放了,正常打印出当前类名称

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. 用ARC管理内存 ARC(Automatic ReferenceCounting, 自动引用计数),它避免了...
    anyurchao阅读 7,770评论 0 16
  • 视图控制对象通过alloc和init来创建,但是视图控制对象不会在创建的那一刻就马上创建相应的视图,而是等到需要使...
    Coder_JMicheal阅读 3,414评论 0 2
  • 一. 视图控制对象通过alloc和init来创建,但是视图控制对象不会在创建的那一刻就马上创建相应的视图,而是等到...
    iOS菜鸟攻城狮阅读 3,759评论 0 7
  • 内存优化工具 Instruments的Allocations 这个工具能显示出应用的实际内存占用,并可以按大小进行...
    Foxhoundsun阅读 5,254评论 0 10
  • 基础优化策略 延迟分配&懒分配 高效初始化内存malloc分配的小块内存,并不会保证清零初始化,一般会配上mems...
    人生看淡不服就干阅读 6,936评论 0 4

友情链接更多精彩内容