先使用 Xcode Energy Gauge 分析出哪一块耗电(网络和 motion , 仍是定位 ... ), 用 Time Profiler 定位问题与解决 ( Instruments 模版 ), 获得用户好的反馈。html
好比: 网络请求,先压缩数据git
网络请求,使用缓存机制,设置内容验证( 须要的数据是否更新了 ),或者缓存的失效时间github
合并网络请求。一次请求大量数据,比屡次请求少许数据省电swift
(类比 CPU,线程开多了很差。开线程,就会有消耗)api
WWDC 推荐使用 Xcode Debug 栏的 Energy Debug Gauge。xcode
( 调性能,都是用真机。机器老一点,效果更好 )缓存
Energy Debug Gauge 形象、直观bash
可看出,当前手机的耗电状况,耗电低、高、很高。苹果的三个阶段,有些不太细致。(左上的 Utilization, Current Impact)网络
app 的平均能耗,一目了然 ( 右上的 Average ) 。app
每个时刻,耗电的是什么。 CPU 、网络、文件 I/O 、定位,哪些消耗了。( 中间的 Energy Impact )
好比:
分析 CPU 使用的 time profile, (可以知道代码的执行状况了,根据函数的调用消耗。找出权重大的,干掉没必要要的。)
分析网络活动的 network profile, 分析定位活动的 location profile
这里电量消耗很高,很稳定
主要是 CPU 和网络请求在耗电。
使用 Instruments 的 Time Profiler 分析,
能够先放大上面的 time line,再选择一个时间段,在调用树 call tree 中,进一步分析。
Time Profiler 的选项默认是按线程划分的,再选一个隐藏系统调用函数。
(系统执行的函数,能够参考一下,到底发生了什么。系统的改不了。能够改本身的源代码 )
在调用树的表格中,按权重展开 ( weight ),要干掉的就是权重大的,耗时间的。
接着展开主线程 ( main thread 。看上图,其余线程的耗时,相比主线程的,可忽略 ), 按住 Option 键,点击 main thread 左边的小三角,能够一会儿展开不少。
可清晰看出,耗时严重的是 450 毫秒左右的那一行 thunk for ... CMDeviceMotion? ...
里面调用了一个耗时的方法,CatPhotoTableViewCell.panImage
, 上图, 454 毫秒中,占 419 毫秒。
点击进入详情,就看到代码了。
在 CatFeedViewController 的 viewDidLoad 方法中,有一个倾斜的设置
motionManager.startDeviceMotionUpdates(to: .main, withHandler:{ deviceMotion, error in
guard let deviceMotion = deviceMotion else { return }
let xRotationRate = CGFloat(deviceMotion.rotationRate.x)
let yRotationRate = CGFloat(deviceMotion.rotationRate.y)
let zRotationRate = CGFloat(deviceMotion.rotationRate.z)
// y > z, 这个动做是翘起来
// y > x + z, 这个动做是斜着翘起来
if abs(yRotationRate) > (abs(xRotationRate) + abs(zRotationRate)) {
for cell in self.tableView.visibleCells as! [CatPhotoTableViewCell] {
cell.panImage(with: yRotationRate)
}
}
})
复制代码
如今的代码显示栏 ( 原来的 Call Tree 表格 ), 右上角有一个 Xcode 的小图标,点击返回 Xcode 调试代码。
手机没动,总是调用 cell.panImage(with: yRotationRate)
, 根本就没效果。
设置一下,调用 cell.panImage
的时候,要超过最小的手机幅度。幅度小,根本就没效果。 添加一个属性记录 lastY
来设置,过滤掉手机小的抖动。
private var lastY = 0.0
override func viewDidLoad() {
super.viewDidLoad()
......
motionManager.startDeviceMotionUpdates(to: .main, withHandler:{ deviceMotion, error in
guard let deviceMotion = deviceMotion else { return }
// 添加了这两行
guard abs(self.lastY - deviceMotion.rotationRate.y) > 0.1 else { return }
self.lastY = deviceMotion.rotationRate.y
let xRotationRate = CGFloat(deviceMotion.rotationRate.x)
let yRotationRate = CGFloat(deviceMotion.rotationRate.y)
let zRotationRate = CGFloat(deviceMotion.rotationRate.z)
if abs(yRotationRate) > (abs(xRotationRate) + abs(zRotationRate)) {
for cell in self.tableView.visibleCells as! [CatPhotoTableViewCell] {
cell.panImage(with: yRotationRate)
}
}
})
}
复制代码
还有一个使用 Timer 定时发送日志的问题,CPU 根本没有空闲的时间,开销很大。
具体见文末的 Demo Code.
最后这样
会慢慢降下去,至于电量低消耗。 须要大约两分钟时间,一屏幕放不下。
由于不能手机在线调试。Energy 是空的, 或者提示 No Data
,
这是苹果的一个长期的 bug .(参见 Apple Forum )
Energy Log 模版的模块挺丰富的,能够看屏幕亮度、定位、蓝牙、GPU 和网络等等的功耗状况,其中网络又包括 WiFi 和蜂窝网络。
想着一边给手机充电,一边调试电量损失,不靠谱。
试了下,无线用 Instruments 的 Energy Log 模版调试,结果同样。
无线链接 Xcode 调试耗电,也没有数据。
无线 debug 功能,隐藏在 Xcode 的 Window > Devices and Simulators 中。
其实是,使用共享的无线网络,取代了数据线的链接,与 Xcode 创建链接。
会有一个网络的 Icon . 上面还有提示语 ( connected , 连上了 )
以下图:
更多参见博客 How to use Wireless Debugging on Xcode 9
而后就能够设置 Instruments 无线设备调试了,
更多参见苹果文档 Energy Efficiency Guide for iOS Apps
WWDC 中说,要看到,就导入离线的 log。(几个月之前,还能用)
在手机的设置中,开发者选项中的 Logging, 选中 Energy, 点击开始录制:
以后,使用你的 app 一段时间,(能够重点测耗电功能) 开发者选项中的 Logging, 点击完成录制, 导入电量消耗 log 数据,到 Instruments 的 Energy Log 模版.
推测老版本的不行( 11.4 ), 没数据。操做的时候,手机的设置 app ,还总是闪退。
手机升级到最新版(12.1 , 20181127),试了屡次,也不行, 猜想目前是完全挂了
(本文中,重启过手机,升级过手机。没试太重启电脑)
耗电是很差的。
写入硬盘与网络请求,都是高耗电操做。
网络的质量与类型,对于耗电的影响也很大。 使用 Wi-Fi 比 3G , 4G 要省电得多。 使用 4G 比 3G 要省电,由于 4G 的信号更强。
通常状况下,app 都用 Timer 作了不少无用功。
好比, 一个列表屏幕, 上方 banner 计时器,往下滑到看不见 banner ,就能够暂停计时器。上滑,看得见 banner 了,又能够恢复 resume。
一样的,进入子界面,能够选择暂停 Timer,或者释放,...
例子: 定时作重复的大量工做很差,可能每当系统休眠(系统要下降能级了),系统又被唤醒了,开始功耗。
与网络请求相似,手机设备定位经过 GPS 天线发送信号,也挺耗电的。
若是 app 常常去获取手机设备的精肯定位,定位精度越高,能耗越严重。 建议使用策略,手机的负担会小不少。
( 🌰,Deferred location updates, 位置更新延迟(直到移动了 x 米或者时间超过了 xx 秒 )、
significant location change, 定位变化比较大的时候,唤醒、
region monitoring, 监测用户进入或离开特定地理区域)
使用罗盘、陀螺仪、加速计,都消耗不小。
更多资料:
WWDC 2015 Debugging Energy Issues
本文 Demo 使用的是 500 px 的 API .
后来发现, 有人都写过了,
想了一下,能够写他没交代的。苹果更新太快,人是物非