我最近正在开发一个涉及在后台进行数据获取的项目,并注意到调度到主队列的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:似乎无法正常工作。
答案 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;
}