GCD实用总结
图片下载
- 注:iOS开发中常见GCD的实用也就这些了,
先来看看之前我们经常使用的方式:
1 static NSOperationQueue * queue; 2 3 - (IBAction)someClick:(id)sender { 4 self.indicator.hidden = NO; 5 [self.indicator startAnimating]; 6 queue = [[NSOperationQueue alloc] init]; 7 NSInvocationOperation * op = [[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil] autorelease]; 8 [queue addOperation:op]; 9 } 10 11 - (void)download { 12 NSURL * url = [NSURL URLWithString:@"http://www.youdao.com"]; 13 NSError * error; 14 NSString * data = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error]; 15 if (data != nil) { 16 [self performSelectorOnMainThread:@selector(download_completed:) withObject:data waitUntilDone:NO]; 17 } else { 18 NSLog(@"error when download:%@", error); 19 [queue release]; 20 } 21 } 22 23 - (void) download_completed:(NSString *) data { 24 NSLog(@"call back"); 25 [self.indicator stopAnimating]; 26 self.indicator.hidden = YES; 27 self.content.text = data; 28 [queue release]; 29 }
使用 GCD 后
如果使用 GCD,以上 3 个方法都可以放到一起,如下所示:
1 // 原代码块一 2 self.indicator.hidden = NO; 3 [self.indicator startAnimating]; 4 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 5 // 原代码块二 6 NSURL * url = [NSURL URLWithString:@"http://www.youdao.com"]; 7 NSError * error; 8 NSString * data = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error]; 9 if (data != nil) { 10 // 原代码块三 11 dispatch_async(dispatch_get_main_queue(), ^{ 12 [self.indicator stopAnimating]; 13 self.indicator.hidden = YES; 14 self.content.text = data; 15 }); 16 } else { 17 NSLog(@"error when download:%@", error); 18 } 19 });
首先我们可以看到,代码变短了。因为少了原来 3 个方法的定义,也少了相互之间需要传递的变量的封装。
block 有如下特点:
- 程序块可以在代码中以内联的方式来定义。
- 程序块可以访问在创建它的范围内的可用的变量。
GCD无处不在
系统提供的 dispatch 方法——最常使用
为了方便地使用 GCD,苹果提供了一些方法方便我们将 block 放在主线程 或 后台线程执行,或者延后执行。使用的例子如下:
1 // 后台执行: 2 dispatch_async(dispatch_get_global_queue(0, 0), ^{ 3 // something 4 }); 5 // 主线程执行: 6 dispatch_async(dispatch_get_main_queue(), ^{ 7 // something 8 }); 9 // 一次性执行: 10 static dispatch_once_t onceToken; 11 dispatch_once(&onceToken, ^{ 12 // code to be executed once 13 }); 14 // 延迟 2 秒执行: 15 double delayInSeconds = 2.0; 16 dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 17 dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 18 // code to be executed on the main queue after delay 19 });
后台运行
使用 block 的另一个用处是可以让程序在后台较长久的运行。在以前,当 app 被按 home 键退出后,app 仅有最多 5 秒钟的时候做一些保存或清理资源的工作。但是应用可以调用 UIApplication 的beginBackgroundTaskWithExpirationHandler方法,让 app 最多有 10 分钟的时间在后台长久运行。这个时间可以用来做清理本地缓存,发送统计数据等工作。
让程序在后台长久运行的示例代码如下:
1 // AppDelegate.h 文件 2 @property (assign, nonatomic) UIBackgroundTaskIdentifier backgroundUpdateTask; 3 4 // AppDelegate.m 文件 5 - (void)applicationDidEnterBackground:(UIApplication *)application 6 { 7 [self beingBackgroundUpdateTask]; 8 // 在这里加上你需要长久运行的代码 9 [self endBackgroundUpdateTask]; 10 } 11 12 - (void)beingBackgroundUpdateTask 13 { 14 self.backgroundUpdateTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ 15 [self endBackgroundUpdateTask]; 16 }]; 17 } 18 19 - (void)endBackgroundUpdateTask 20 { 21 [[UIApplication sharedApplication] endBackgroundTask: self.backgroundUpdateTask]; 22 self.backgroundUpdateTask = UIBackgroundTaskInvalid; 23 }
时间: 2024-10-26 04:58:24