我可以使用 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 developer Guide

回答我自己的问题。来自 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.

其他Apple API reference:

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.