我的应用程序中定期启动了一些NSOperations
。即使将应用程序置于后台,它们也应该完成。为此,我使用beginBackgroundTaskWithExpirationHandler
方法。
我是否应该在每次启动任务时使用beginBackgroundTaskWithExpirationHandler
/ endBackgroundTask:
,即使应用程序没有进入后台?或者我只是在检测到UIApplicationDidEnterBackgroundNotification
时才调用开始/结束方法?
选项1:每次都使用后台任务
/**
* This method is called regularly from a NSTimer
*/
- (void)processData
{
__block UIBackgroundTaskIdentifier operationBackgroundId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:operationBackgroundId];
operationBackgroundId = UIBackgroundTaskInvalid;
}];
NSOperation *operation = ...
[self.queue addOperation:operation];
operation.completionBlock = ^{
[[UIApplication sharedApplication] endBackgroundTask:operationBackgroundId];
operationBackgroundId = UIBackgroundTaskInvalid;
};
}
选项2:仅在应用程序即将进入后台时使用后台任务
/**
* This method is called regularly from a NSTimer
*/
- (void)processData
{
NSOperation *operation = ...
[self.queue addOperation:operation];
}
- (void)applicationDidEnterBackground:(NSNotification *)notification
{
__block UIBackgroundTaskIdentifier operationBackgroundId = [[UIApplication sharedApplication] beginBackgroundTaskWithName:@"EnterBackgroundFlushTask" expirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:operationBackgroundId];
operationBackgroundId = UIBackgroundTaskInvalid;
}];
// wait for all operations to complete and then
// let UIApplication know that we are done
[[UIApplication sharedApplication] endBackgroundTask:operationBackgroundId];
}
答案 0 :(得分:6)
回答我自己的问题。来自Apple Docs:
您无需等到应用移至后台即可 指定后台任务。一个更有用的设计是调用 beginBackgroundTaskWithName:expirationHandler:或 beginBackgroundTaskWithExpirationHandler:开始之前的方法 任务并在完成后立即调用endBackgroundTask:方法。您 你的应用程序在执行时,甚至可以遵循这种模式 前景。
您应该在未完成任务的情况下调用此方法,这可能会损害您应用的用户体验。
您可以在应用执行的任何时候调用此方法。
答案 1 :(得分:-1)
Option2 是正确的选项。这是Apple文档中的代码供您参考。
- (void)applicationDidEnterBackground:(UIApplication *)application
{
bgTask = [application beginBackgroundTaskWithName:@"MyTask" expirationHandler:^{
// Clean up any unfinished task business by marking where you
// stopped or ending the task outright.
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do the work associated with the task, preferably in chunks.
[self processData];
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
}