iOS后台任务完成编程

时间:2012-06-12 21:40:54

标签: objective-c xcode ios4 multitasking

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

到委托函数,或者我是否需要做其他事情。

先谢谢你的帮助, Guvvy

2 个答案:

答案 0 :(得分:6)

根据您对dispatch_async的通话,您已经在后台主题中。该方法将立即返回,但您的块将继续运行。

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

如果你在你的委托中杀死background_task的路线,你还必须创建一个ivar来存储background_task,这样你的委托方法就可以了。这看起来有点沉重。

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

答案 1 :(得分:-2)

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

[application endBackgroundTask: background_task];
background_task = UIBackgroundTaskInvalid;

当您的任务过期时,iOS会调用您的handlerExpiration方法来终止它。 有关详情,请访问Background for iOS