zoukankan      html  css  js  c++  java
  • iOS-GCD处理后台线程和UI线程的交互

    一个例子:

    在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);

    }

    });

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

    系统提供的dispatch方法

    为了方便地使用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;

    }

  • 相关阅读:
    poj1661【DP,左右两端dp】
    hdoj1074【A的无比爆炸】
    hdoj1024【DP.最 大 m 字 段 和】(写完我都怕。。。不忍直视。。)
    qq教xixi写模拟加法【非常爆炸】
    错排公式
    POJ3616【基础DP】
    hdoj1257【疑问】(贪心)
    【弱的C艹之路。。未完待续】
    hdoj1728【搜索的两种写法】
    hdoj1001【智障了。。。】
  • 原文地址:https://www.cnblogs.com/linxiu-0925/p/5442549.html
Copyright © 2011-2022 走看看