xcode iOS后台任务完成编程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11005291/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 00:35:10  来源:igfitidea点击:

iOS Background Task Completion Programming

objective-cxcodeios4multitasking

提问by Gavy

I'm trying to add support for completing a task after exiting the foreground for my iOS App. All the tutorials I saw on the internet point me to writing something like this in the Application Delegate:

我正在尝试为我的 iOS 应用程序退出前台后添加对完成任务的支持。我在互联网上看到的所有教程都指向我在 Application Delegate 中编写如下内容:

- (void)applicationDidEnterBackground:(UIApplication *)application {
    if ([[UIDevice currentDevice] isMultitaskingSupported]) {
        UIApplication *application = [UIApplication sharedApplication];
        __block UIBackgroundTaskIdentifier background_task;
        background_task = [application beginBackgroundTaskWithExpirationHandler: ^ {
            [application endBackgroundTask: background_task];
            background_task = UIBackgroundTaskInvalid;
        }];

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

            //DO STUFF IN BACKGROUND HERE
            MyTask *task = [[MyTask alloc] initWithURL:@"http://google.com"];
            [task setDelegate:self];
            [task start];

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

The task is able to start, but after it starts, the next line gets processed and my app is killed. I am able to tell when MyTaskstops due to a delegate call, but how do I change my program so that the background task gets set to invalid after the delegate gets called. Would I move

该任务能够启动,但在它启动后,下一行被处理并且我的应用程序被终止。我能够知道何时MyTask因委托调用而停止,但是如何更改我的程序,以便在调用委托后将后台任务设置为无效。我会搬家吗

[application endBackgroundTask: background_task];
background_task = UIBackgroundTaskInvalid;

to the delegate function, or do I need to do something else.

到委托功能,还是我需要做其他事情。

Thanks in advance for your help, Guvvy

预先感谢您的帮助,Guvvy

回答by djibouti33

You're already in a background thread per your call to dispatch_async. That method will return immediately, but your block will continue to run.

每次调用dispatch_async. 该方法将立即返回,但您的块将继续运行。

Your problem seems to be that your start method runs another asynchronous process, so that method returns immediately, and your background task is killed before [task start]is able to do anything meaningful.

您的问题似乎是您的 start 方法运行另一个异步进程,因此该方法立即返回,并且您的后台任务在[task start]能够执行任何有意义的操作之前被终止。

If you go the route of killing background_taskin your delegate, you'll also have to create an ivar to store background_taskso your delegate methods can get to it. That seems a little heavy handed.

如果你background_task在你的委托中去杀戮,你还必须创建一个 ivar 来存储,background_task以便你的委托方法可以访问它。这似乎有点沉重。

Since you're already in a background thread, my suggestion would be for you to refactor [task start]so it's synchronous. That way, all the meaningful work will be performed before the next line is processed and background_taskis killed. This seems cleaner, and everything for your background task is nicely wrapped in the block sent to dispatch_async.

由于您已经在后台线程中,我的建议是让您重构[task start]以使其同步。这样,所有有意义的工作都将在下一行被处理和终止之前执行background_task。这看起来更干净,并且您的后台任务的所有内容都很好地包装在发送到 dispatch_async 的块中。

回答by David Nguyen

You can completely remove following code:

您可以完全删除以下代码:

[application endBackgroundTask: background_task];
background_task = UIBackgroundTaskInvalid;

When your task is expired, iOS will call your handlerExpiration method to kill it. For more information, please visit Background for iOS

当你的任务过期时,iOS 会调用你的 handlerExpiration 方法来终止它。有关更多信息,请访问iOS 背景