一个例子:

在iPhone上做一个下载网页的功能,就是:在iPhone上放一个按钮,单击按钮时,显示一个转动的圆圈,表示正在进行下载,下载完成后,将内容加载到界面上的一个文本控件上。

使用GCD前:

static NSOperationQueue *queue;

// 按钮的点击事件

-(void)someClick:(id)sender{

self.indicator.hidden = NO;

[self.indicator startAnimating];

queue = [NSOperationQueue alloc]init];

NSInvocationOperation *op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download) object:nil];

[queue addOperation:op];

}

-(void)download{

NSURL *url = [NSURL URLWithString:@"http://www.youdao.com"];

NSError *error;

NSString *data = [NSString stringWithContentOfURL:url encoding:NSUTF8StringEncoding error:&error];

if(data !=nil){

 [self performSelectorOnMainThread:@selector(download_complexted:) withObject:data waitUntilDone:NO];

}else{

  NSLog(@"%@",error);

}

}

-(void)download_complexted:(NSString *)data{

[self.indicator stopAnimating];

self.indicator.hidden = YES;

self.content.text = data;

}

使用GCD以前分成了三部分来写。

使用GCD后,以上三个方法可以放在一起:

self.indicator.hidden = NO;

[self.indicator startAnimating];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{

          NSURL *url = [NSURL URLWithString:@"http://www.youdao.com"];

          NSError *error;

          NSString *data = [NSString stringWithContentOfURL:url encoding:NSUTF8StringEncoding error:&error];

if(data !=nil){

dispatch_async(diapatch_get_main_queue(),^{

[self.indicator stopAnimating];

self.indicator.hidden = YES;

self.content.text = data;

});

}else{

  NSLog(@"%@",error);

}

});

首先,看到代码变短了,变清楚了。

 

为了方便地使用GCD,苹果提供了一些方法方便我们将block放在主线程或后台线程执行,或者延后执行。使用的例子如下所示:

 //  后台执行:
 dispatch_async(dispatch_get_global_queue(0, 0), ^{
      // something
 });

 // 主线程执行:
 dispatch_async(dispatch_get_main_queue(), ^{
      // something
 });

 // 一次性执行:
 static dispatch_once_t onceToken;
 dispatch_once(&onceToken, ^{
     // code to be executed once
 });

 // 延迟2秒执行:
 double delayInSeconds = 2.0;
 dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
 dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
     // code to be executed on the main queue after delay
 });


dispatch_queue_t也可以自己定义,如要自定义queue,可以用dispatch_queue_create方法,示例如下:
 // 自定义dispatch_queue_t
 dispatch_queue_t urls_queue = dispatch_queue_create("blog.devtang.com", NULL);
 dispatch_async(urls_queue, ^{  
   // your code 
 });
 dispatch_release(urls_queue);

另外,GCD还有一些高级用法,例如让后台两个线程并行执行,然后等两个线程都结束后,再汇总执行结果。这个可以用dispatch_group_t、dispatch_group_async、dispatch_group_notify来实现,示例如下:

 // 合并汇总结果
 dispatch_group_t group = dispatch_group_create();
 dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
      // 并行执行的线程一
 });
 dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
      // 并行执行的线程二
 });
 dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^{
      // 汇总结果
 });

修改block之外的变量,只需将__block引用在外部即可。

后台的运行:

在appdelegate.h

@property (assign,nonatomic)UIBackgroundTaskIdentifier backgroundUpdateTask;

在appdelegate.m

- (void)applicationDidEnterBackground:(UIApplication *)application {
   
    
    [self beginBackgroundUpdateTask];
    
    //在这里加上你需要长久运行的代码
    
    [self endBackgroundUpdateTask];
    
}
-(void)beginBackgroundUpdateTask{


    self.backgroundUpdateTask = [[UIApplication sharedApplication]beginBackgroundTaskWithExpirationHandler:^{
        [self endBackgroundUpdateTask];
    }];

}
-(void)endBackgroundUpdateTask{

    [[UIApplication sharedApplication]endBackgroundTask:self.backgroundUpdateTask];
    
    self.backgroundUpdateTask = UIBackgroundTaskInvalid;

}

相关文章:

  • 2021-11-23
  • 2022-12-23
  • 2022-02-15
  • 2022-01-08
  • 2022-12-23
  • 2021-08-05
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-01-04
  • 2021-09-21
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案