GCD和UIBackgroundTaskIdentifier

时间:2011-09-16 01:31:51

标签: objective-c cocoa-touch grand-central-dispatch long-running-processes

我有一个调度队列,其中有一些工作。我希望队列继续运行,直到任何时间用完或队列耗尽,当应用程序进入后台时。我如何设置UIBackgroundTaskIdentifier?

我是否需要将其放入调度块中?

    dispatch_async(queue, ^{
        if (_bgTask == UIBackgroundTaskInvalid) {
            if ([UIDevice currentDevice].multitaskingSupported) {
                _bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^(void) {
                    if (_bgTask != UIBackgroundTaskInvalid) {
                        [[UIApplication sharedApplication] endBackgroundTask:_bgTask];
                        _bgTask = UIBackgroundTaskInvalid;
                    }
                }];
            }
        }

...
...

        if (_bgTask != UIBackgroundTaskInvalid) {
                    [[UIApplication sharedApplication] endBackgroundTask:_bgTask];
                    _bgTask = UIBackgroundTaskInvalid;
                }

            });

我认为上面发生的事情是,在队列实际运行块之前,它没有被注册为长时间运行的任务。那么我是否需要将代码的背景部分放在块之外,以便它在实际排队之前执行?

2 个答案:

答案 0 :(得分:3)

我不确定你为什么要跟踪我认为是伊娃的UIBackgroundTaskID。最简单的方法是:

UIBackgroundTaskIdentifier btid = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{...}];
dispatch_async(queue, ^{
    ... // Your code...
    [[UIApplication sharedApplication] endBackgroundTask:btid];
}

答案 1 :(得分:1)

如果您有一个包含工作项的调度队列,并且您转到后台,则队列将继续处理其任务180秒(iOS 7及更高版本)。之后,操作系统会自动暂停所有操作。所以不再是NSThreads,NSTimers甚至是NSOperationQueues。一切都暂停了。

因此,我不确定您要在应用层中添加哪些额外代码来实现您要执行的操作。它是预制的。