编辑一个场景。在iPhone上做一个下载网页的功能,就是在界面上放一个按钮,单击该按钮时,先是一个转动的圆圈,表示正在进行下载,下载完成后,将内容加载到界面上的一个文本控件中。
使用GCD之前:
someClick方法是单击按钮后的响应,使用NSInvocatinOperation创建一个后台线程,并且放到NSOperationQueue中。后台线程执行download方法。
download方法处理下载网页的逻辑。下载完成后用performSelectorOnMainThread执行download_completed方法。
download_completed进行clear up的工作,并把下载的内容显示到文本控件中。
方法如下:
static NSOperationQueue *queue;
//使用GCD方法之前
//代码块1 开始下载
self.indicator.hidden = NO;
[self.indicator startAnimating];
queue = [[NSOperationQueue alloc]init];
NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download) object:nil];
[queue addOperation:operation];
}
//代码块2 下载中
- (void)download{
NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];
NSError *error;
NSString *data = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
if (data != nil) {
[self performSelectorOnMainThread:@selector(download_completed:) withObject:data waitUntilDone:NO];
}else{
NSLog(@"error when download:%@",error);
}
}
//代码块3 下载完成
- (void)download_completed:(NSString *)data{
NSLog(@"call back");
[self.indicator stopAnimating];
self.indicator.hidden = YES;
self.content.text = data;
}
使用GCD后,以上三个方法合为一起。
- (void)someClick:(UIButton *)sender{
//原代码块1
self.indicator.hidden = NO;
[self.indicator startAnimating];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//原代码块2
NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];
NSError *error;
NSString *data = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
if (data != nil) {
//原代码块3
dispatch_async(dispatch_get_main_queue(), ^{
[self.indicator stopAnimating];
self.indicator.hidden = YES;
self.content.text = data;
});
}else{
NSLog(@"error when download:%@",error);
}
});
}
使用GCD方法可以大量减少代码量、使代码逻辑清晰可见。使用起来更加方便。