3

我正在尝试在退出我的 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;
        });
    }
}

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

[application endBackgroundTask: background_task];
background_task = UIBackgroundTaskInvalid;

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

提前感谢您的帮助,古维

4

2 回答 2

6

根据您对 的调用,您已经在后台线程中dispatch_async。该方法将立即返回,但您的块将继续运行。

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

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

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

于 2012-09-06T21:40:44.280 回答
-2

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

[application endBackgroundTask: background_task];
background_task = UIBackgroundTaskInvalid;

当你的任务过期时,iOS 会调用你的 handlerExpiration 方法来杀死它。有关更多信息,请访问iOS 后台

于 2013-09-24T09:37:43.550 回答