美文网首页iOS常用
iOS监测应用被杀死并做一些处理

iOS监测应用被杀死并做一些处理

作者: 鄂北 | 来源:发表于2020-05-02 20:27 被阅读0次

    在一些业务需求中,我们需要在app退出到后台或者杀死的时候做一些业务上的处理。在AppDelegate中提供了相关的方法。

    APP进入后台

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

    在后台进入到后台时会调起这个方法,我们可以在这个方法里做一些相关的处理。在app进入后台后几分钟应用会自动被杀死,applicationDidEnterBackground里我们可以调个方法监测到在后台应用即将被杀死的时候,并在应用被杀死前做业务上的相关处理。

    // APP进入后台
    - (void)applicationDidEnterBackground:(UIApplication *)application {
        [[UIApplication sharedApplication]beginBackgroundTaskWithExpirationHandler:^{
            //在应用杀死前在这里可以做出业务上的一些处理
        }];
    }
    

    beginBackgroundTaskWithExpirationHandler的详细用法可以看这位大神的beginBackgroundTaskWithExpirationHandler

    上面说的是应用进入到后台几分钟后被系统自动杀死的情况,但是还有种情况是应用被用户往上划手动杀死的。在应用被用户手动杀死时会AppDelegate调用下面的方法

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

    在这里需要注意一个问题:在applicationWillTerminate中做一些主线程的事情是没有问题,但是如果是做一些异步的处理,会发现应用杀死了,但是异步处理的事情并没有完成。比如我想在应用被手动杀死时向服务器发起请求,这个请求还没请求完应用就被杀死了,所以服务器接受不到客服端的请求。

    -(void)applicationWillTerminate:(UIApplication *)application {
    // 在应用杀死时向服务器发起请求,但是这里服务器接受不到客服端的请求,因为应用已经被杀死了
        [[[YFServiceManager sharedManager] getPersonService]requestAnchorOnlineStateWithOnlineState:@"6" WithSuccess:^(id  _Nonnull response) {
           
        } withFailure:^(NSError * _Nonnull error) {
           
        }];
    }
    

    小编在这里使用了信号量处理,将异步的网络请求达到了任务同步执行的要求

    -(void)applicationWillTerminate:(UIApplication *)application {
        //创建信号量
        dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
        [[[YFServiceManager sharedManager] getPersonService]requestAnchorOnlineStateWithOnlineState:@"6" WithSuccess:^(id  _Nonnull response) {
            //发起信号量
            dispatch_semaphore_signal(semaphore);
        } withFailure:^(NSError * _Nonnull error) {
            //发起信号量
            dispatch_semaphore_signal(semaphore);
        }];
        //等待信号量,如果没收到信号量主线程会被阻塞,应用不会被杀死。只有等到网络请求成功或失败后发起信号量,主线程接受到信号量,主线程才会被执行完,应用才会被杀死
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    }
    

    信号量是一个非负整数,定义了两种原子操作:wait跟signal来进行访,信号量主要用于线程同步。当一个线程调用wait操作时,如果信号量的值大于0,则获得资源并将信号量值减一,如果等于0线程睡眠直到信号量值大于0或者超时;singal将信号量的值加1,如果这时候有正在等待的线程,唤醒该线程。
    信号量的详细介绍和使用可以看这位大神的GCD信号量-dispatch_semaphore_t

    至此监测应用被杀死的问题已经介绍完毕,但是小编还想再提几句,不想看的可以忽略。

    beginBackgroundTaskWithExpirationHandler方法中做网络请求可以成功,并不需要做信号量处理。但是这个成功的前提是beginBackgroundTaskWithExpirationHandler方法是在applicationDidEnterBackground方法中执行的,如果是放在applicationWillTerminate方法中是不会的

    这个不需要做信号量处理,网络请求仍然能成功

    // APP进入后台
    - (void)applicationDidEnterBackground:(UIApplication *)application {
        [[UIApplication sharedApplication]beginBackgroundTaskWithExpirationHandler:^{
            //在应用杀死前在这里可以做出业务上的一些处理
            //这这里不需要做信号量的处理就能完成网络数据的请求
        }];
    }
    

    相关文章

      网友评论

        本文标题:iOS监测应用被杀死并做一些处理

        本文链接:https://www.haomeiwen.com/subject/ntokghtx.html