2015-04-25 41 views
0

我有应用程序,它使用后台提取和更新位置。它工作正常使用此代码:iOS - 后台提取和线程

-(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方法运行另一个后台操作,例如从互联网上下载数据,我遇到了问题。下载是异步启动的,因此在数据交付之前,我的后台提取“backgroundFetchCompletionHandler”处于“关闭”状态。数据超出了这个范围,我恐怕会造成一些问题。如何正确解决这个问题?

编辑: 我不能修改_delegate代码,所以通过处理程序作为变量不是一个选项。

回答

1

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

+0

问题是我无法修改_delegate代码,所以传递处理程序是不可能的。 –

+0

为什么你不能修改它?如果它没有告诉你什么时候完成,那么你真的没有选择... – Wain

+0

我不能直接修改_delegate,但是在下载数据之后_delegate cals选择器,并从那里管理数据并将它们填充到CoreData。但是LocationManager和Selector没有看到对方。因此,唯一的解决方案就是使用“静态共享”变量并通过它传递处理程序。 (或许有更巧妙的ios样式解决方案) –