iOS - 后台获取和线程

iOS - background fetch and threads

我有一个应用程序,它在运行期间使用后台获取和更新位置。它适用于此代码:

-(void)backgroundDidUpdateLocations:(NSArray *)locations
{    
    UIApplication *app = [UIApplication sharedApplication];
    __block UIBackgroundTaskIdentifier locationUpdateTaskID = [app beginBackgroundTaskWithExpirationHandler:
    ^{
        dispatch_async(dispatch_get_main_queue(),
        ^{            
            if (locationUpdateTaskID != UIBackgroundTaskInvalid)
            {

                if (_backgroundFetchCompletionHandler != nil)
                {
                    NSLog(@"BG location finished 1");
                    _backgroundFetchCompletionHandler(UIBackgroundFetchResultNewData);
                    _backgroundFetchCompletionHandler = nil;
                }

                [app endBackgroundTask:locationUpdateTaskID];
                locationUpdateTaskID = UIBackgroundTaskInvalid;
            }
        });
    }];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
    ^{                        
        if (_delegate && [_delegate respondsToSelector:@selector(myLocationManager:didUpdateLocations:)])
        {
            [_delegate myLocationManager:self didUpdateLocations:locations];
        }

        dispatch_async(dispatch_get_main_queue(),
        ^{            
            if (locationUpdateTaskID != UIBackgroundTaskInvalid)
            {
                if (_backgroundFetchCompletionHandler != nil)
                {
                    NSLog(@"BG location finished 2");
                    _backgroundFetchCompletionHandler(UIBackgroundFetchResultNewData);
                    _backgroundFetchCompletionHandler = nil;
                }

                [app endBackgroundTask:locationUpdateTaskID];
                locationUpdateTaskID = UIBackgroundTaskInvalid;
            }
        });
    });

}

但是这有一个问题:

[_delegate myLocationManager:self didUpdateLocations:locations];

如果我使用一些简单的调用,就可以了。但是如果 _delegate 方法运行一些其他后台操作,比如从互联网下载数据,我就有问题了。下载是异步启动的,所以我的后台提取是 "closed" 和 backgroundFetchCompletionHandler,然后才交付数据。数据超出了这个范围,恐怕会导致一些问题。如何正确解决这个问题?

编辑: 我无法修改 _delegate 代码,因此无法将处理程序作为变量传递。

如果委托已设置并响应,则将完成处理程序传递给它,以便它可以完成工作并在完成时调用完成处理程序。如果委托未设置或未响应,则直接调用完成处理程序。