iOS App 電量消耗優(yōu)化

App耗電方式主要分為:
1,CPU計(jì)算
通過(guò)方法查看當(dāng)前CPU使用率,然后獲取當(dāng)前方法堆棧,就可以定位耗電原因。
首先獲取線程信息

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);

threads 結(jié)構(gòu)體如下

struct thread_basic_info {
        time_value_t    user_time;      /* user 運(yùn)行的時(shí)間 */
        time_value_t    system_time;    /* system 運(yùn)行的時(shí)間 */
        integer_t       cpu_usage;      /* CPU 使用百分比 */
        policy_t        policy;         /* 有效的計(jì)劃策略 */
        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;     /* 休眠時(shí)間 */
};

判斷cpu_usage就可以知道當(dāng)前CPU的使用百分比,較高的情況即是耗電較多的情況


// 輪詢檢查多個(gè)線程 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 時(shí)打印和記錄堆棧
                    NSString *reStr = smStackOfThread(threads[i]);
                    //記錄數(shù)據(jù)庫(kù)中
                    [[[SMLagDB shareInstance] increaseWithStackString:reStr] subscribeNext:^(id x) {}];
                    NSLog(@"CPU useage overload thread stack:\n%@",reStr);
                }
            }
        }
    }
}

GCD 的 dispatch_block_create_with_qos_class 方法指定隊(duì)列的 Qos 為 QOS_CLASS_UTILITY,將計(jì)算工作放到這個(gè)隊(duì)列的 block 里。在 QOS_CLASS_UTILITY 這種 Qos 模式下,系統(tǒng)針對(duì)大量數(shù)據(jù)的計(jì)算,以及復(fù)雜數(shù)據(jù)處理專門(mén)做了電量?jī)?yōu)化。

2,I/O 操作
I/O 操作會(huì)破壞低功耗狀態(tài),所以要減少操作次數(shù)??梢韵仁褂肗SCache來(lái)存儲(chǔ),等數(shù)據(jù)存儲(chǔ)達(dá)到閾值之后再將數(shù)據(jù)進(jìn)行I/O操作。比如我們常見(jiàn)的SDWebImage 就是這樣實(shí)現(xiàn)的


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

- (UIImage *)imageFromDiskCacheForKey:(NSString *)key {
    // 檢查 NSCache 里是否有
    UIImage *image = [self imageFromMemoryCacheForKey:key];
    if (image) {
        return image;
    }
    // 從磁盤(pán)里讀
    UIImage *diskImage = [self diskImageForKey:key];
    if (diskImage && self.shouldCacheImagesInMemory) {
        NSUInteger cost = SDCacheCostForImage(diskImage);
        [self.memCache setObject:diskImage forKey:key cost:cost];
    }
    return diskImage;
}

NSCache 是線程安全的,NSCache 會(huì)在到達(dá)預(yù)設(shè)緩存空間值時(shí)清理緩存,這時(shí)會(huì)觸發(fā) cache:willEvictObject: 方法的回調(diào),在這個(gè)回調(diào)里就可以對(duì)數(shù)據(jù)進(jìn)行 I/O 操作,達(dá)到將聚合的數(shù)據(jù) I/O 延后的目的。I/O 操作的次數(shù)減少了,對(duì)電量的消耗也就減少了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、在后臺(tái)工作量少 當(dāng)用戶沒(méi)有主動(dòng)使用你的應(yīng)用程序時(shí),系統(tǒng)會(huì)將其轉(zhuǎn)換為背景狀態(tài)。該系統(tǒng)最終可能會(huì)暫停您的應(yīng)用程序,...
    弗利撒閱讀 977評(píng)論 1 0
  • 一 優(yōu)化CPU耗電 耗時(shí)長(zhǎng)處理 對(duì)于大量復(fù)雜計(jì)算,應(yīng)該把數(shù)據(jù)傳到服務(wù)器處理,如果必須在APP內(nèi)處理,可以通過(guò)GCD...
    旅途的喵閱讀 1,646評(píng)論 0 4
  • 算法時(shí)間復(fù)雜度: 在集合里數(shù)據(jù)量小的情況下時(shí)間復(fù)雜度對(duì)于性能的影響看起來(lái)微乎其微。但如果某個(gè)開(kāi)發(fā)的功能是一個(gè)公共功...
    __blossom閱讀 553評(píng)論 0 0
  • 本文是來(lái)自@ShawnSun的投稿 一款好的App一定要有非常好的用戶體驗(yàn),這一點(diǎn)已經(jīng)是大多數(shù)開(kāi)發(fā)者的共識(shí)。功耗是...
    SmallDe閱讀 3,160評(píng)論 0 50
  • 電池壽命長(zhǎng)。隨著能效降低,電池壽命也會(huì)降低。但用戶想讓自己的移動(dòng)設(shè)備全天候待命。 速度快。iOS系統(tǒng)處理復(fù)雜操作時(shí)...
    武_IOS書(shū)閱讀 1,615評(píng)論 0 3

友情鏈接更多精彩內(nèi)容