首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >苹果编程指南iOS后台执行指南示例?

苹果编程指南iOS后台执行指南示例?
EN

Stack Overflow用户
提问于 2016-01-22 16:38:26
回答 3查看 643关注 0票数 4

因此,在这个页面上有一个关于后台执行的示例:ref/doc/uid/TP40007072-CH4-SW1,下面是示例:

代码语言:javascript
复制
- (void)applicationDidEnterBackground:(UIApplication *)application {

    bgTask = [application beginBackgroundTaskWithName:@"MyTask" expirationHandler:^{

        // Clean up any unfinished task business by marking where you
        // stopped or ending the task outright.
        [application endBackgroundTask:bgTask];

        bgTask = UIBackgroundTaskInvalid;
    }];

    // Start the long-running task and return immediately.
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        // Do the work associated with the task, preferably in chunks.

        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    });

}

据说,bgTask在类中被定义为变量。因此,类(对象)的每个实例都有一个bgTask属性。如果applicationDidEnterBackground在异步块完成之前被多次调用,那么这里不是存在种族状况的危险吗?我的意思是bgTask会改变它的值,而endBackgroundTask将被调用到新的任务值上,而不是旧的值上?

这不是一个更好的解决方案:

代码语言:javascript
复制
__block UIBackgroundTaskIdentifier bgTask;

在调用beginBackgroundTaskWithName之前

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-01-28 19:46:31

每个对象都有一个bgTask实例,但这是在AppDelegate上,而不是一些普通的VC或对象上。因此,从技术上讲,只有一个bgTask实例在起作用。

但这仍然会带来问题。因为如果这个方法被调用两次,它将覆盖bgTask的值。我的第一个想法是,一旦退出应用程序,不止一次,所有以前的任务都将过期。但在测试后发现情况并非如此(这是一件好事,海事组织)。发生的事情是,bgTask被覆盖(正如预期的那样),新值被传递给第一个endBackgroundTask:调用。紧接着,bgTask被设置为UIBackgroundTaskInvalid,这将清除它,并将清除的值传递给对endBackgroundTask:的任何后续调用。这显然导致了一个不干净的终止,因为并不是所有唯一的id都已经结束,导致expiration处理程序在任何遗留的后台任务上执行。

话虽如此,我相信你关于使用局部变量的假设是正确的。如果您尝试使用此代码(放置在AppDelegate applicationDidEnterBackground:中):

代码语言:javascript
复制
__block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithName:@"MyTask" expirationHandler:^{
    // Clean up any unfinished task business by marking where you
    // stopped or ending the task outright.
    NSLog(@"Expired");
    [application endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
}];

NSLog(@"Backgrounded: %@", @(bgTask));

// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    // Do the work associated with the task, preferably in chunks.
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"Done! %@", @(bgTask));
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    });
});

您将看到每个本地bgTask都分配了一个唯一值,并在10秒后正确完成(按照dispatch_after调用)。

票数 2
EN

Stack Overflow用户

发布于 2016-01-25 13:12:27

我认为你要解决的问题如下:

一个应用程序被发送到Background状态,iOS调用applicationDidEnterBackground:

一个背景任务开始了,可能需要几分钟的时间。

在此期间,应用程序再次被激活,并再次发送到后台,后者再次调用applicationDidEnterBackground:,并启动另一个后台任务,如果变量bgTask不是块变量,则该任务将被覆盖。这是正确的。因此,bgTask确实应该是一个块变量。

与此相关的问题是,如果启动了多个后台任务,如何完成后台执行。给出了一个例子,您可以这样做,给出了here

这样做的目的是要有一个变量来统计活动的后台任务。一旦它们全部完成,就可以终止后台执行。

票数 1
EN

Stack Overflow用户

发布于 2016-01-30 16:55:19

您是正确的,当第二次被要求时,applicationDidEnterBackground会引起问题。但是,为了使该方法再次被调用,首先需要将该应用程序放到前台。所以解决办法很简单。只需从applicationWillEnterForeground调用过期处理程序即可

代码语言:javascript
复制
- (void)expireBackgroundTask {
    // Clean up any unfinished task business by marking where you
    // stopped or ending the task outright.
    [application endBackgroundTask:bgTask];            
    bgTask = UIBackgroundTaskInvalid;
}

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

    bgTask = [application beginBackgroundTaskWithName:@"MyTask" expirationHandler:^{
        [self expireBackgroundTask];
    }];

    // Start the long-running task and return immediately.
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        // Do the work associated with the task, preferably in chunks.

        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    });

}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    [self expireBackgroundTask];
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34951661

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档