我的应用程序需要执行一些与互联网相关的操作,然后在将应用程序发送到后台时弹出该视图。然后根视图控制器获取一些数据并更新集合视图。您是否知道我如何解决与上述操作相关的以下问题(顺便说一下,我使用本地通知来启动该过程):
1)UI相关操作(弹出当前视图控制器)似乎在后台失败。
2)当我将视图弹出到根视图控制器时,Root视图有一些nsurlconnection,它将数据发送到其委托。由于长时间运行的任务在全局队列中运行,因此nsurlconnection似乎无法向其委托发送任何信息。
我在此过程中使用以下代码:
UIBackgroundTaskIdentifier __block bgTask;
UIApplication *app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self performOperation];
NSLog(@"Operation finished");
});
答案 0 :(得分:-1)
正如matt指出的那样,当应用程序在后台时,你无法执行UI操作,例如弹出视图控制器。当应用程序返回到前台时(例如,用户再次点击图标),则可能会发生弹出(如果应用程序未在此期间完全终止)。
我认为亚马的观察回答了你的第二个问题。如果没有,请澄清你的意思。但是UIBackgroundTaskIdentifier
的这种使用并不关心你是使用全局队列还是自定义队列或其他什么。唯一的限制是不会发生某些UI操作,因此不会发生任何意外情况,例如viewDidAppear
。
顺便说一句,我想指出,当执行任务的代码完成时,您真的想要调用endBackgroundTask
,而代码示例似乎没有这样做。请参阅 iOS应用程序编程指南的应用程序状态和多任务章节的Executing a Finite-Length Task in the Background。
因此,您可以执行以下操作:
UIApplication *app = [UIApplication sharedApplication];
UIBackgroundTaskIdentifier __block bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
NSLog(@"Operation did not finish!!!");
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self performOperation];
NSLog(@"Operation finished");
if (bgTask != UIBackgroundTaskInvalid) {
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
});