【iOS-性能优化一】卡顿产生的原因

一、优化CPU

  • 尽量用轻量级的对象,比如用不到事件处理的地方,可以考虑使用CALayer取代UIView;
  • 不要频繁地调用 UIView的相关属性,比如frame、bounds、transform等属性,尽量减少不必要的修改
  • 尽量提前计算好布局,在有需要时一次性调整对应的属性,不要多次修改属性
  • Autolayout会比真设置frame消耗更多的CPU资源
  • 图片的size最好刚好好UIImageView的size保持一致
  • 控制一下线程的最大并发数量
  • 尽量把耗时的操作放到子线程
  • 文本处理(尺寸计算、绘制)
  • 图片处理(解码、绘制)

例:把图片的解码操作放到子线程

UIImageView *imgeView = [[UIImageView alloc] init];
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
       
        CGImageRef cgImage = [UIImage imageNamed:@""].CGImage;
        
        CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(cgImage) &
                            kCGBitmapAlphaInfoMask;
        BOOL hasAlpha = NO;
        if (alphaInfo == kCGImageAlphaPremultipliedLast ||
            alphaInfo==kCGImageAlphaPremultipliedFirst ||
            alphaInfo == kCGImageAlphaLast ||
            alphaInfo == kCGImageAlphaFirst) {
            hasAlpha = YES;
        }
        
        CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Host;
        
        bitmapInfo |= hasAlpha ? kCGImageAlphaPremultipliedFirst :
                            kCGImageAlphaNoneSkipFirst;
        
        size_t width = CGImageGetWidth(cgImage);
        size_t height = CGImageGetHeight(cgImage);
        
        //context
        CGContextRef context = CGBitmapContextCreate(NULL, width, height, 8, 0,
                                                     CGColorSpaceCreateDeviceRGB(), bitmapInfo);
        
        // draw
        CGContextDrawImage(context, CGRectMake(0, 0, width, height), cgImage);
        
        // get CGImage
        cgImage = CGBitmapContextCreateImage(context);
        
        // into UIImage
        UIImage *newImage = [UIImage imageWithCGImage:cgImage];
        
        // realease
        CGContextRelease(context);
        CGImageRelease(cgImage);
        
        // back to the main thread
        dispatch_async(dispatch_get_main_queue(), ^{
            imgeView.image = newImage;
        });
        
    });

二、优化GPU

  • 尽量减少视图数量和层次
  • 尽量避免短时间内大量图片的显示,尽可能将多张图片合成一张进行显示
  • GPU能处理的最大纹理尺寸是4096*4096,一旦超过这个尺寸,就会占有用CPU资源进行处理,所以纹理尽量不要超过这个尺寸
  • 减少透明的视图,不透明的就设置 opaque 为yes
  • 尽量避免出现离屏渲染
关于离屏渲染

三、卡顿检测

  • 卡顿,主要因为在主线程执行了耗时操作
  • 可以添加Observer到主线程RunLoop中,通过监听RunLoop状态切换的耗时,以达到监控卡顿的目的

这是一个用来监听卡顿的工具包:
https://github.com/UIControl/LXDAppFluecyMonitor

四、耗电优化

  • 尽可能少CPU/GPU功耗

  • 少用定时器

  • 优化IO操作

  • 不要频繁写入小数据,最好批量一次性写入

  • 数据量比较大时,使用数据库(SQLite、CoreData)

  • 网络优化(XML 、 JSON 、 protocol buffer)

  • 减少、压缩网络数据

  • 多次请求,结果一样的话,使用缓存

  • 使用断点续传

  • 网络不可用时,不要尝试执行网络请求

  • 设置合适的超时时间

  • 批量传输,减少请求数量

  • 如果只是快速确定用户位置 ,使用CLLocationManager的 requestLocation,定位完成会自动断电

  • 如果不是导航APP,尽量不要实时更新位置,定位完毕就关掉定位服务

  • 尽量降低定位精度,比如尽量不要使用精度最高的kCLLocationAccuracyBest

  • 需要后台定位时,尽量设置pausesLocationUpdatesAutomaticallyYES,如果用户不太可能移动的时候系统会自动暂停位置更新

  • 尽量不要使用 startMonitoringSignificantLocationChages,优先考虑 startMonitoringForRegion

  • 用户移动、摇晃、倾斜设备时,会产生动作 motion 事件,这些事件由加速计、陀螺仪、磁力计等三件检测。在不需要检测的场合,应该及时关闭这些硬件

你可能感兴趣的:(【iOS-性能优化一】卡顿产生的原因)