iOS監(jiān)測(cè)應(yīng)用被殺死并做一些處理

在一些業(yè)務(wù)需求中,我們需要在app退出到后臺(tái)或者殺死的時(shí)候做一些業(yè)務(wù)上的處理。在AppDelegate中提供了相關(guān)的方法。

APP進(jìn)入后臺(tái)

- (void)applicationDidEnterBackground:(UIApplication *)application 
{

}

在后臺(tái)進(jìn)入到后臺(tái)時(shí)會(huì)調(diào)起這個(gè)方法,我們可以在這個(gè)方法里做一些相關(guān)的處理。在app進(jìn)入后臺(tái)后幾分鐘應(yīng)用會(huì)自動(dòng)被殺死,applicationDidEnterBackground里我們可以調(diào)個(gè)方法監(jiān)測(cè)到在后臺(tái)應(yīng)用即將被殺死的時(shí)候,并在應(yīng)用被殺死前做業(yè)務(wù)上的相關(guān)處理。

// APP進(jìn)入后臺(tái)
- (void)applicationDidEnterBackground:(UIApplication *)application {
    [[UIApplication sharedApplication]beginBackgroundTaskWithExpirationHandler:^{
        //在應(yīng)用殺死前在這里可以做出業(yè)務(wù)上的一些處理
    }];
}

beginBackgroundTaskWithExpirationHandler的詳細(xì)用法可以看這位大神的beginBackgroundTaskWithExpirationHandler

上面說(shuō)的是應(yīng)用進(jìn)入到后臺(tái)幾分鐘后被系統(tǒng)自動(dòng)殺死的情況,但是還有種情況是應(yīng)用被用戶(hù)往上劃手動(dòng)殺死的。在應(yīng)用被用戶(hù)手動(dòng)殺死時(shí)會(huì)AppDelegate調(diào)用下面的方法

-(void)applicationWillTerminate:(UIApplication *)application {
  
}

在這里需要注意一個(gè)問(wèn)題:在applicationWillTerminate中做一些主線(xiàn)程的事情是沒(méi)有問(wèn)題,但是如果是做一些異步的處理,會(huì)發(fā)現(xiàn)應(yīng)用殺死了,但是異步處理的事情并沒(méi)有完成。比如我想在應(yīng)用被手動(dòng)殺死時(shí)向服務(wù)器發(fā)起請(qǐng)求,這個(gè)請(qǐng)求還沒(méi)請(qǐng)求完應(yīng)用就被殺死了,所以服務(wù)器接受不到客服端的請(qǐng)求。

-(void)applicationWillTerminate:(UIApplication *)application {
// 在應(yīng)用殺死時(shí)向服務(wù)器發(fā)起請(qǐng)求,但是這里服務(wù)器接受不到客服端的請(qǐng)求,因?yàn)閼?yīng)用已經(jīng)被殺死了
    [[[YFServiceManager sharedManager] getPersonService]requestAnchorOnlineStateWithOnlineState:@"6" WithSuccess:^(id  _Nonnull response) {
       
    } withFailure:^(NSError * _Nonnull error) {
       
    }];
}

小編在這里使用了信號(hào)量處理,將異步的網(wǎng)絡(luò)請(qǐng)求達(dá)到了任務(wù)同步執(zhí)行的要求

-(void)applicationWillTerminate:(UIApplication *)application {
    //創(chuàng)建信號(hào)量
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    [[[YFServiceManager sharedManager] getPersonService]requestAnchorOnlineStateWithOnlineState:@"6" WithSuccess:^(id  _Nonnull response) {
        //發(fā)起信號(hào)量
        dispatch_semaphore_signal(semaphore);
    } withFailure:^(NSError * _Nonnull error) {
        //發(fā)起信號(hào)量
        dispatch_semaphore_signal(semaphore);
    }];
    //等待信號(hào)量,如果沒(méi)收到信號(hào)量主線(xiàn)程會(huì)被阻塞,應(yīng)用不會(huì)被殺死。只有等到網(wǎng)絡(luò)請(qǐng)求成功或失敗后發(fā)起信號(hào)量,主線(xiàn)程接受到信號(hào)量,主線(xiàn)程才會(huì)被執(zhí)行完,應(yīng)用才會(huì)被殺死
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}

信號(hào)量是一個(gè)非負(fù)整數(shù),定義了兩種原子操作:wait跟signal來(lái)進(jìn)行訪(fǎng),信號(hào)量主要用于線(xiàn)程同步。當(dāng)一個(gè)線(xiàn)程調(diào)用wait操作時(shí),如果信號(hào)量的值大于0,則獲得資源并將信號(hào)量值減一,如果等于0線(xiàn)程睡眠直到信號(hào)量值大于0或者超時(shí);singal將信號(hào)量的值加1,如果這時(shí)候有正在等待的線(xiàn)程,喚醒該線(xiàn)程。
信號(hào)量的詳細(xì)介紹和使用可以看這位大神的GCD信號(hào)量-dispatch_semaphore_t

至此監(jiān)測(cè)應(yīng)用被殺死的問(wèn)題已經(jīng)介紹完畢,但是小編還想再提幾句,不想看的可以忽略。

beginBackgroundTaskWithExpirationHandler方法中做網(wǎng)絡(luò)請(qǐng)求可以成功,并不需要做信號(hào)量處理。但是這個(gè)成功的前提是beginBackgroundTaskWithExpirationHandler方法是在applicationDidEnterBackground方法中執(zhí)行的,如果是放在applicationWillTerminate方法中是不會(huì)的

這個(gè)不需要做信號(hào)量處理,網(wǎng)絡(luò)請(qǐng)求仍然能成功

// APP進(jìn)入后臺(tái)
- (void)applicationDidEnterBackground:(UIApplication *)application {
    [[UIApplication sharedApplication]beginBackgroundTaskWithExpirationHandler:^{
        //在應(yīng)用殺死前在這里可以做出業(yè)務(wù)上的一些處理
        //這這里不需要做信號(hào)量的處理就能完成網(wǎng)絡(luò)數(shù)據(jù)的請(qǐng)求
    }];
}
最后編輯于
?著作權(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ù)。

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