iOS:当应用程序状态为UIApplicationStateBackground时,为什么在主线程运行时不会调度dispatch_async?

时间:2016-08-30 18:11:43

标签: ios objective-c multithreading

我最近正在开发一个涉及在后台进行数据获取的项目,并注意到调度到主队列的dispatch_async块将无法运行。

测试条件: - 应用程序具有后台提取和远程通知功能 - 通过配置为通过iPhone 6S Plus上的后台获取启动的方案启动

示例代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

     dispatch_async(dispatch_get_main_queue(), ^{
          NSLog(@"Won't run");
     });

      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

          NSLog(@"I ran");

          dispatch_async(dispatch_get_main_queue(), ^{
               NSLog(@"Won't run");
          });

          dispatch_sync(dispatch_get_main_queue(), ^{
               NSLog(@"Won't run");
          });
     });

     return YES;
}

问题: 1)有谁知道这是为什么?我找不到任何文件。不可否认,我可能正在寻找错误的地方 - 到目前为止,我已经检查了dispach_async上的GCD文档,并进行了一些繁重的网络搜索。 2)有没有其他方法(最好是基于GCD的)我甚至可以在后台对主线程进行异步调用?

编辑:performSelectorOnMainThread:似乎无法正常工作。

2 个答案:

答案 0 :(得分:0)

问题似乎是我没有在我的AppDelegate中包含委托方法应用程序:performFetchWithCompletionHandler:由于某种原因,在没有实现此方法的情况下触发后台提取会将块调度到主线程上。

答案 1 :(得分:0)

我的解决方案是通过调用:

来标记后台任务的开始
self.backgroundTask = [application beginBackgroundTaskWithExpirationHandler:^ {
        [application endBackgroundTask:self.backgroundTask];
        weakSelf.backgroundTask = UIBackgroundTaskInvalid;
    }];

当后台任务完成时,需要通过调用来平衡:

if (self.backgroundTask != UIBackgroundTaskInvalid) {
    [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask];
    self.backgroundTask = UIBackgroundTaskInvalid;
}