某些时候后台任务在模拟器上失败/总是在设备上失败

时间:2012-10-18 13:48:16

标签: ios

我在-applicationDidEnterBackground中启动后台任务,如果用户更改了与推送通知相关的设置,则会将数据上传到我的服务器。当用户更改设置时,我将静态BOOL设置为YES,并仅在应用程序进入后台时发送更改。我将结束任务的a块传递给方法,所以当到达connectionDidFinishLoading时,它会调用它并结束任务。

它在模拟器上大部分时间都有效,但在实际设备上无效。

相关代码:

self.bgTask = [application beginBackgroundTaskWithExpirationHandler:^
 {
     [application endBackgroundTask:self.bgTask];
     self.bgTask = UIBackgroundTaskInvalid;
 }];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
   {
       [PushInfo checkDirty:^{
           NSLog(@"push info sent");
           [application endBackgroundTask:self.bgTask];
           self.bgTask = UIBackgroundTaskInvalid;
       }];
   });
...
// in PushInfo.m :
typedef void (^VoidBlock)();
static BOOL dirty;

+ (void) checkDirty:(VoidBlock)endBlock
{
    if(dirty)
    {
        PushInfo *pi = [[PushInfo alloc] init];
        NSLog(@"sending pushinfo");             // This code is always reached
        [pi setEndBlock:endBlock];
        [pi updatePushInfo];
    }
    else
        endBlock();
}

- (void) updatePushInfo
{
   ...
   // Create a NSURLConnection to send the data
   ...
}

- (void) connectionDidFinishLoading:(NSURLConnection *)connection
{
  ...
  NSLog(@"sent push info");
  dirty = NO;
  if(endBlock)
  {
    endBlock();
  }
}

我错过了什么吗? 编辑:即使它确实在模拟器上将信息发送到服务器,静态变量由于某种原因仍然是YES ...

2 个答案:

答案 0 :(得分:1)

尝试将代码移至:

- (void)applicationWillResignActive:(UIApplication *)application

我认为在applicationDidEnterBackground中使用它已经太晚了。

检查了文档,你是对的,它应该在applicationDidEnterBackground中没问题。

另一个建议是,尝试在dispatch_async块中移动beginBackgroundTaskWithExpirationHandler。 可能必须在同一个线程中启动,但没有在文档中明确说明这一点。

答案 1 :(得分:0)

结束使用+ sendSynchronousRequest:returningResponse:error: