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
iOS Background Task Completion Programming
提问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 MyTask
stops 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_task
in your delegate, you'll also have to create an ivar to store background_task
so 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_task
is 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 背景