beginBackgroundTaskWithExpirationHandler

直接代码

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    __block uibackgroundtaskIdentifier background_task;
    //注册一个后台任务,告诉系统我们需要向系统借一些事件
    background_task = [application beginBackgroundTaskWithExpirationHandler:^ {
        
        //不管有没有完成,结束background_task任务
        [application endBackgroundTask: background_task];
        background_task = uibackgroundtaskInvalid;
    }];

    /*
     尽量用异步,如果像这样 你会发现主线程会被阻塞
     while(TRUE)
     {
     NSLog(@"Background time Remaining: %f",[[UIApplication sharedApplication] backgroundTimeRemaining]);
     [NSThread sleepForTimeInterval:1]; //wait for 1 sec
     }
     */
    //异步
    dispatch_async(dispatch_get_global_queue(disPATCH_QUEUE_PRIORITY_DEFAULT,0),^{
        
        //### background task starts
        NSLog(@"Running in the background\n");
        
        static int i = 0;
        while(i < 5)
        {
            NSLog(@"Background time Remaining: %f",[[UIApplication sharedApplication] backgroundTimeRemaining]);
            [NSThread sleepForTimeInterval:1]; //wait for 1 sec
            i++;
        }
        /*
         while(TRUE)
         {
         NSLog(@"Background time Remaining: %f",[[UIApplication sharedApplication] backgroundTimeRemaining]);
         [NSThread sleepForTimeInterval:1]; //wait for 1 sec
         i++;
         }
         */
        
        //我们自己完成任务后,结束background_task任务
        //如果我们用while(TRUE)的话,下面这两行代码应该不会执行
        [application endBackgroundTask: background_task];
        background_task = uibackgroundtaskInvalid;
    });
}

Despite its name, beginBackgroundTaskWithExpirationHandler: does not actually "begin" a task. It might be better thought of as "register..." rather than "begin...." You're just telling the system that you're in the middle of doing something that would like to complete if that's ok.

Several points:

  • In almost all cases,you want to call beginBackgroundTaskWithExpirationHandler: when you start doing the thing you want to do,and then endBackgroundTask: when you're done. You almost never call these at the point that the user presses the Home button (unless that's the point when you start the task,such as saving something to the server).

  • You can have as many "background tasks" as you want open at a time. They cost nothing. They're like retain counts. As long as you still have one open (a "begin" that did not get to its "end"),then the system will consider that a request for more time. There is very little cost to calling the "begin" and "end" methods,so use these to bracket anything that you want extra time to finish.

  • There is no way to be certain that you will get to finish your sync. These methods just make a request. The OS may still deny that request. The OS may still kill you anytime it needs some extra resources. The OS is not infinitely patient; if you take too long (about 10 minutes usually),it'll kill you anyway after calling your expiration handler. The OS may kill you because the phone is being turned off. Your app must be able to deal with not getting to finish. The OS just gives you this ability so that you can improve the user experience

相关文章

我正在用TitaniumDeveloper编写一个应用程序,它允许我使用Ja...
我的问题是当我尝试从UIWebView中调用我的AngularJS应用程序...
我想获取在我的Mac上运行的所有前台应用程序的应用程序图标....
我是一名PHP开发人员,我使用MVC模式和面向对象的代码.我真的...
OSX中的SetTimer在Windows中是否有任何等效功能?我正在使用...
我不确定引擎盖下到底发生了什么,但这是我的设置,示例代码和...