我可以使用 beginBackgroundTaskWithName 进行正常的应用程序处理吗
Can I use beginBackgroundTaskWithName for normal app processing
我有一些 NSOperations
在我的应用程序中定期启动。即使应用程序置于后台,它们也应该完成。为此,我使用 beginBackgroundTaskWithExpirationHandler
方法。
我是否应该在每次开始我的任务时都使用 beginBackgroundTaskWithExpirationHandler
/endBackgroundTask:
,即使应用程序不会进入后台?或者我是否应该仅在检测到 UIApplicationDidEnterBackgroundNotification
时才调用 begin/end 方法?
选项 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];
}
选项2是正确的option.Here是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;
});
}
回答我自己的问题。来自 Apple Docs:
You do not need to wait until your app moves to the background to
designate background tasks. A more useful design is to call the
beginBackgroundTaskWithName:expirationHandler: or
beginBackgroundTaskWithExpirationHandler: method before starting a
task and call the endBackgroundTask: method as soon as you finish. You
can even follow this pattern while your app is executing in the
foreground.
You should call this method at times where leaving a task unfinished might be detrimental to your app’s user experience.
You can call this method at any point in your app’s execution.
我有一些 NSOperations
在我的应用程序中定期启动。即使应用程序置于后台,它们也应该完成。为此,我使用 beginBackgroundTaskWithExpirationHandler
方法。
我是否应该在每次开始我的任务时都使用 beginBackgroundTaskWithExpirationHandler
/endBackgroundTask:
,即使应用程序不会进入后台?或者我是否应该仅在检测到 UIApplicationDidEnterBackgroundNotification
时才调用 begin/end 方法?
选项 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];
}
选项2是正确的option.Here是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;
});
}
回答我自己的问题。来自 Apple Docs:
You do not need to wait until your app moves to the background to designate background tasks. A more useful design is to call the beginBackgroundTaskWithName:expirationHandler: or beginBackgroundTaskWithExpirationHandler: method before starting a task and call the endBackgroundTask: method as soon as you finish. You can even follow this pattern while your app is executing in the foreground.
You should call this method at times where leaving a task unfinished might be detrimental to your app’s user experience.
You can call this method at any point in your app’s execution.