我让我的应用使用dispatch_async进行谷歌API调用并获取我正在解析的JSON结果。我想实现一个进度视图,以便根据我解析过的JSON响应的结果进行更新。
所以我的dispatch_async Google API调用是:
dispatch_async(myQueue, ^{
NSData* data1 = [NSData dataWithContentsOfURL:googleURL];
[self performSelectorOnMainThread:@selector(fetchResultsForGoogle:) withObject:data1 waitUntilDone:YES];
});
我的fetchResultsForGoogle: withObject:
方法解析结果,我想在屏幕上显示进度视图,其中包含已处理结果的数量。所以在fetchResultsForGoogle...
方法中,我希望:
float percentage = (float)counter/(float)totalItems;
self.progressView.progress = percentage;
NSString *percentText = [NSString stringWithFormat:@"%f %% %@", percentage, @" complete"];
self.progressViewLabel.text = percentText;
但我认为理解当dispatch_async在另一个线程上执行时,您无法在不使用dispatch_async(dispatch_get_main_queue()
的情况下更新主线程上的视图。为了解决这个问题,我尝试了两种方法来实现这一点(如下所示),但这些方法中的任何一种都不适合我(progressView
和progressViewLabel
不要更新全部)。
计划A:
dispatch_async(myQueue, ^{
NSData* data1 = [NSData dataWithContentsOfURL:googleURL];
[self performSelectorOnMainThread:@selector(fetchResultsForGoogle:) withObject:data1 waitUntilDone:YES];
dispatch_async(dispatch_get_main_queue(), ^{
float percentage = (float)counter/(float)totalItems;
self.progressView.progress = percentage;
NSString *percentText = [NSString stringWithFormat:@"%f %% %@", percentage, @"complete"];
NSLog(@"Percentage: %@", percentText);
self.progressViewLabel.text = percentText;
});
});
B计划:
dispatch_async(myQueue, ^{
NSData* data1 = [NSData dataWithContentsOfURL:googleURL];
[self performSelectorOnMainThread:@selector(fetchResultsForGoogle:) withObject:data1 waitUntilDone:YES];
});
在fetchResultsForGoogle...
方法中:
dispatch_async(dispatch_get_main_queue(), ^{
float percentage = (float)counter/(float)totalItems;
self.progressView.progress = percentage;
NSString *percentText = [NSString stringWithFormat:@"%f %% %@", percentage, @"complete"];
NSLog(@"Percentage: %@", percentText);
self.progressViewLabel.text = percentText;
});
因此,非常感谢有关实施此方法的正确方法的任何想法或提示!
编辑解决方案
我修好了它。在dispatch_async
块中,我将其传递给performSelectorOnMainThread
。因此,当我尝试更新performSelectorOnMainThread
中的进度视图时,用户界面不会更新,直到dispatch_async
完成。
因此,我将其更改为performSelectorInBackgroundThread
块内的dispatch_async
,现在performSelectorOnMainThread
更新了UI,就像它应该的那样。
我是这一切的新手,但我很高兴我还在学习新事物。
答案 0 :(得分:0)
你是对的,你不能以你的方式更新主线程中的东西。您必须在主线程上执行选择器,如下所示:
我不确定你的百分比在哪里发生变化,但是在那里添加一行。它会在主线程上更新你的标签和progressView
[self performSelectorOnMainThread:@selector(updateProgress:) withObject:[NSNumber numberWithFloat:percentage] waitUntilDone:NO];
-(void) updateProgress:(NSNumber *) num {
float percentage = [num floatValue];
self.progressView.progress = percentage;
NSString *percentText = [NSString stringWithFormat:@"%f %% %@", percentage, @" complete"];
self.progressViewLabel.text = percentText;
}