先使用 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 .
後來發現, 有人都寫過了,
想了一下,能夠寫他沒交代的。蘋果更新太快,人是物非