Title不重要
  • 初衷
  • 教程
    • Aria2教程
    • Mac重装教程
    • Hexo教程
    • v2ray教程
    • 翻墙教程
    • Flutter教程
    • Cocoapods教程
  • 混合框架
    • 方案一:原生+H5
      • a、Cordova
      • b、Ionic
      • c、微信小程序
    • 方案二:原生+JavaScript
      • a、React Native
      • b、Weex
      • c、快应用
    • 方案三:原生+自绘
      • a、QT for mobile
      • b、Flutter
  • 开发语言
    • Flutter
      • Dart
    • iOS
      • 1、Swift
      • 2、Objective-C
    • Android
      • Java
    • 2、Python
    • 3、JavaScript
    • 4、PHP
    • 5、Go
  • 开发者
    • 开发者个人
      • iOS
    • 开发者团队
      • 滴滴出行团队
      • 携程团队
      • Yelp团队
      • 大众点评-美团点评团队
  • 工具
    • Mac
      • 重装Mac
    • Windows
  • 干货
    • iOS干货
      • 音视频
      • 动画
      • 直播
      • Xcode
      • iOS 网站论坛
      • iOS 开源项目
        • Swift
      • iOS 视图控件
    • 书籍
      • 教育类
    • 其他干货
      • 设计干货
      • 电影网站
      • Telegram资源
    • Java干货
    • Android干货
      • Android 开源项目
  • 集成平台
    • 第三方支付
      • 微信支付
    • 高德地图
      • AMapSearch库
  • SDKS
    • iOS
      • Foundation
        • NSURLSession
  • 互联网概念
    • 后端
      • 黑石物理服务器
      • Redis
      • 360 Pika项目
      • MapReduce
      • Apache Kylin
      • Gears
      • 集群框架Spark
      • ACM国际大学生程序设计竞赛
      • Presto
      • Apache Storm
      • Apache Flink
      • Apache HBase
      • Apache Mesos
      • Apache Hadoop
      • Apache Hive
      • Apache Cassandra
      • LAMP
      • MySQL
      • 概念:微服务
    • 前端
      • iOS
        • 怎么知道一个NSObject对象占用多少内存?
        • Token过期的处理方案
        • 无侵入埋点
        • 电量优化
        • 介绍多线程
        • 介绍消息传递和转发
        • 介绍Runloop
        • 介绍Runtime
        • 介绍深拷贝和浅拷贝
        • 介绍KVO和KVC
        • 自定义的类,如何实现copy
        • 介绍Autorelease对象什么时候释放?
        • 介绍App卡顿
        • 介绍NSCoding协议和NSCopying协议
        • 介绍内存泄漏和内存溢出
        • 介绍Weak和Assign的区别
        • 介绍Delegate为什么用Weak
      • Android
        • Android中startService和bindService的区别
        • Android与vue js互相调用
      • 原理:直播流程
  • 互联网大会
    • QCon全球软件开发大会
    • AICon全球人工智能与机器学习大会
    • ArchSummit全球架构师峰会
    • GMTC全球大前端技术大会
      • 2019 GMTC
    • WWDC全球苹果开发者大会
      • WWDC2019
        • SwiftUI
      • WWDC2017
        • Universal Links
      • WWDC2018
      • WWDC资源
    • 谷歌I/O大会
  • 生活的智慧
    • 权谋学
Powered by GitBook
On this page
  • 获取电量
  • 查看哪个线程耗电高
  • 优化cpu耗电问题
  • 优化I/O操作耗电问题
  • 苹果电量优化最佳实践

Was this helpful?

  1. 互联网概念
  2. 前端
  3. iOS

电量优化

获取电量

1.导入文件

2.设置监控为true

#import "IOPSKeys.h"
#import "IOPowerSources.h"

-(double) getBatteryLevel{
    // 返回电量信息
    CFTypeRef blob = IOPSCopyPowerSourcesInfo();
    // 返回电量句柄列表数据
    CFArrayRef sources = IOPSCopyPowerSourcesList(blob);
    CFDictionaryRef pSource = NULL;
    const void *psValue;
    // 返回数组大小
    int numOfSources = CFArrayGetCount(sources);
    // 计算大小出错处理
    if (numOfSources == 0) {
        NSLog(@"Error in CFArrayGetCount");
        return -1.0f;
    }

    // 计算所剩电量
    for (int i=0; i<numOfSources; i++) {
        // 返回电源可读信息的字典
        pSource = IOPSGetPowerSourceDescription(blob, CFArrayGetValueAtIndex(sources, i));
        if (!pSource) {
            NSLog(@"Error in IOPSGetPowerSourceDescription");
            return -1.0f;
        }
        psValue = (CFStringRef) CFDictionaryGetValue(pSource, CFSTR(kIOPSNameKey));

        int curCapacity = 0;
        int maxCapacity = 0;
        double percentage;

        psValue = CFDictionaryGetValue(pSource, CFSTR(kIOPSCurrentCapacityKey));
        CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &curCapacity);

        psValue = CFDictionaryGetValue(pSource, CFSTR(kIOPSMaxCapacityKey));
        CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &maxCapacity);

        percentage = ((double) curCapacity / (double) maxCapacity * 100.0f);
        NSLog(@"curCapacity : %d / maxCapacity: %d , percentage: %.1f ", curCapacity, maxCapacity, percentage);
        return percentage;
    }
    return -1.

查看哪个线程耗电高

查看线程中电量使用情况

1.通过线程信息中的threads数组里的线程信息结构体的thread_basic_info里面有一个记录CPU使用百分比的字段cpu_usage

struct thread_basic_info {
        time_value_t    user_time;      /* user 运行的时间 */
        time_value_t    system_time;    /* system 运行的时间 */
        integer_t       cpu_usage;      /* CPU 使用百分比 */
        policy_t        policy;         /* 有效的计划策略 */
        integer_t       run_state;      /* run state (see below) */
        integer_t       flags;          /* various flags (see below) */
        integer_t       suspend_count;  /* suspend count for thread */
        integer_t       sleep_time;     /* 休眠时间 */
};

有了这个cpu_usage字段,就可以遍历所有线程,查看哪个线程cpu使用百分比过高

// 轮询检查多个线程 CPU 情况
+ (void)updateCPU {
    thread_act_array_t threads;
    mach_msg_type_number_t threadCount = 0;
    const task_t thisTask = mach_task_self();
    kern_return_t kr = task_threads(thisTask, &threads, &threadCount);
    if (kr != KERN_SUCCESS) {
        return;
    }
    for (int i = 0; i < threadCount; i++) {
        thread_info_data_t threadInfo;
        thread_basic_info_t threadBaseInfo;
        mach_msg_type_number_t threadInfoCount = THREAD_INFO_MAX;
        if (thread_info((thread_act_t)threads[i], THREAD_BASIC_INFO, (thread_info_t)threadInfo, &threadInfoCount) == KERN_SUCCESS) {
            threadBaseInfo = (thread_basic_info_t)threadInfo;
            if (!(threadBaseInfo->flags & TH_FLAGS_IDLE)) {
                integer_t cpuUsage = threadBaseInfo->cpu_usage / 10;
                if (cpuUsage > 90) {
                    //cup 消耗大于 90 时打印和记录堆栈
                    NSString *reStr = smStackOfThread(threads[i]);
                    // 记录数据库中
                    [[[SMLagDB shareInstance] increaseWithStackString:reStr] subscribeNext:^(id x) {}];
                    NSLog(@"CPU useage overload thread stack:\n%@",reStr);
                }
            }
        }
    }
}

优化cpu耗电问题

1.避免在app处理大量复杂的数据计算,把数据传到服务器去处理

2.对一定要在app处理的复杂计算,通过gcd的dispatch_block_create_with_qos_class方法指定队列的qos为QOS_CLASS_UTILITY,因为他对电量做了优化 -------------------优化cpu耗电问题

优化I/O操作耗电问题

1.使用NSCache方式延时对I/0进行操作

2.类似SDWebImage,先缓存到内存中,后缓存到磁盘中

- (UIImage *)imageFromMemoryCacheForKey:(NSString *)key {
    return [self.memCache objectForKey:key];
}

- (UIImage *)imageFromDiskCacheForKey:(NSString *)key {
    // 检查 NSCache 里是否有
    UIImage *image = [self imageFromMemoryCacheForKey:key];
    if (image) {
        return image;
    }
    // 从磁盘里读
    UIImage *diskImage = [self diskImageForKey:key];
    if (diskImage && self.shouldCacheImagesInMemory) {
        NSUInteger cost = SDCacheCostForImage(diskImage);
        [self.memCache setObject:diskImage forKey:key cost:cost];
    }
    return diskImage;
}

苹果电量优化最佳实践

1.可以从cpu、设备唤醒、网络、图形、动画、视频、定位、加速度计、陀螺仪、磁力计、蓝牙等考虑

Previous无侵入埋点Next介绍多线程

Last updated 5 years ago

Was this helpful?

1、

2、

3、

https://developer.apple.com/library/archive/documentation/Performance/Conceptual/EnergyGuide-iOS/index.html
https://developer.apple.com/videos/play/wwdc2017/238/
https://www.jianshu.com/p/4555704f9696