我在我的Tab栏应用程序中使用GCD进行后台下载。
第一步是在-viewWillAppear:
中进行一些后台下载(在加载视图之前设置一些基本数据)。
第二步是-viewDidAppear:
出于某种原因,-viewDidAppear:
中的调度块在-viewWillAppear:
中的调度块之前被称为。
这只在加载应用程序第一次切换到使用GCD背景方法的选项卡后发生一次。切换到另一个选项卡,然后使用GCD背景方法切换回选项卡。第三个(以及所有其余的后续时间)我正在按照预期切换它的工作(首先-viewWillAppear:
然后再-viewDidAppear:
)。
以下是我的代码(-viewWillAppear:
和-viewDidAppear:
)的摘录:
-viewWillAppear:
- (void)viewWillAppear:(BOOL)animated {
DLog(@"viewWillAppear method running");
[super viewWillAppear:animated];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
[self setDiskCareerIds:[CareersParser idsFrom:@"disk"]];
[self setDownloadedCareerIds:[CareersParser idsFrom:@"web"]];
DLog(@"diskCareerIds after being set in viewWillAppear: %@", [self diskCareerIds])
DLog(@"downloadedCareerIds after being set in viewWillAppear: %@", [self downloadedCareerIds])
if ([[self downloadedCareerIds] isEqualToArray:[self diskCareerIds]]) {
DLog(@"viewWillAppear: ids equal, loading careers from disk.");
self.careers = [CareersParser loadCareersFromDisk];
dispatch_async(dispatch_get_main_queue(), ^{
[self.table reloadData];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
});
}
});
//[self downloadData];
}
-viewDidAppear:
- (void)viewDidAppear:(BOOL)animated {
DLog(@"viewDidAppear method running");
[super viewDidAppear:animated];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
if (![[self downloadedCareerIds] isEqualToArray:[self diskCareerIds]]) {
DLog(@"ids not equal, saving careers to disk.");
dispatch_async(dispatch_get_main_queue(), ^{
[self showLoadingView];
});
[CareersParser saveCareersToDisk];
self.careers = [CareersParser loadCareersFromDisk];
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.table reloadData];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
[self removeLoadingView];
});
});
//[self download3];
//[self downloadData];
}
检查Pastie处的调试日志。
答案 0 :(得分:4)
好吧,你正在第一个块(在viewWillAppear中调度的那个)中打印该日志消息之后它已经完成了一堆解析,而不是它实际开始执行时。
问题是全局队列是并发队列。因此,即使您首先安排第一个块,但它有时落后于与其同时执行的另一个块也就不足为奇了。
一个简单的答案是创建一个串行队列,然后你将确保第一个块在第二个块执行之前完成。这似乎是你想要的,对吧?