zoukankan      html  css  js  c++  java
  • iOS开发多线程篇—GCD的基本使用

    iOS开发多线程篇—GCD的基本使用

    一、主队列介绍

    主队列:是和主线程相关联的队列,主队列是GCD自带的一种特殊的串行队列,放在主队列中得任务,都会放到主线程中执行。
    提示:如果把任务放到主队列中进行处理,那么不论处理函数是异步的还是同步的都不会开启新的线程。
    获取主队列的方式:

     dispatch_queue_t queue=dispatch_get_main_queue();

    (1)使用异步函数执行主队列中得任务,代码示例:

     1 //
     2 //  YYViewController.m
     3 //  12-GCD的基本使用(主队列)
     4 //
     5 //  Created by 孔医己 on 14-6-25.
     6 //  Copyright (c) 2014年 itcast. All rights reserved.
     7 //
     8 
     9 #import "YYViewController.h"
    10 
    11 @interface YYViewController ()
    12 
    13 @end
    14 
    15 @implementation YYViewController
    16 
    17 - (void)viewDidLoad
    18 {
    19     [super viewDidLoad];
    20     
    21     //打印主线程
    22      NSLog(@"打印主线程--%@", [NSThread mainThread]);
    23     
    24     //1.获取主队列
    25     dispatch_queue_t queue=dispatch_get_main_queue();
    26     //2.把任务添加到主队列中执行
    27     dispatch_async(queue, ^{
    28         NSLog(@"使用异步函数执行主队列中的任务1--%@",[NSThread currentThread]);
    29     });
    30     dispatch_async(queue, ^{
    31         NSLog(@"使用异步函数执行主队列中的任务2--%@",[NSThread currentThread]);
    32     });
    33     dispatch_async(queue, ^{
    34         NSLog(@"使用异步函数执行主队列中的任务3--%@",[NSThread currentThread]);
    35     });
    36 }
    37 
    38 @end

    执行效果:

     (2)使用同步函数,在主线程中执行主队列中得任务,会发生死循环,任务无法往下执行。示意图如下:

    二、基本使用

    1.问题  

    任务1和任务2是在主线程执行还是子线程执行,还是单独再开启一个新的线程?

     1 //
     2 //  YYViewController.m
     3 //  13-GCD基本使用(问题)
     4 //
     5 //  Created by 孔医己 on 14-6-25.
     6 //  Copyright (c) 2014年 itcast. All rights reserved.
     7 //
     8 
     9 #import "YYViewController.h"
    10 
    11 @interface YYViewController ()
    12 
    13 @end
    14 
    15 @implementation YYViewController
    16 
    17 - (void)viewDidLoad
    18 {
    19     [super viewDidLoad];
    20     //开启一个后台线程,调用执行test方法
    21     [self performSelectorInBackground:@selector(test) withObject:nil];
    22 }
    23 
    24 -(void)test
    25 {
    26     NSLog(@"当前线程---%@",[NSThread currentThread]);
    27     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    28     
    29     //异步函数
    30     dispatch_async(queue, ^{
    31         NSLog(@"任务1所在的线程----%@",[NSThread currentThread]);
    32     });
    33     
    34     //同步函数
    35     dispatch_sync(queue, ^{
    36         NSLog(@"任务2所在的线程----%@",[NSThread currentThread]);
    37     });
    38 }
    39 
    40 @end

    打印结果:

    2.开启子线程,加载图片

     1 //
     2 //  YYViewController.m
     3 //  14-GCD基本使用(下载图片)
     4 //
     5 //  Created by 孔医己 on 14-6-25.
     6 //  Copyright (c) 2014年 itcast. All rights reserved.
     7 //
     8 
     9 #import "YYViewController.h"
    10 
    11 @interface YYViewController ()
    12 @property (weak, nonatomic) IBOutlet UIImageView *imageView;
    13 
    14 @end
    15 
    16 @implementation YYViewController
    17 
    18 - (void)viewDidLoad
    19 {
    20     [super viewDidLoad];
    21     
    22 }
    23 
    24 //当手指触摸屏幕的时候,从网络上下载一张图片到控制器的view上显示
    25 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    26 {
    27     
    28     //1.获取一个全局串行队列
    29     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    30     //2.把任务添加到队列中执行
    31     dispatch_async(queue, ^{
    32         
    33         //打印当前线程
    34         NSLog(@"%@",[NSThread currentThread]);
    35       //3.从网络上下载图片
    36         NSURL *urlstr=[NSURL URLWithString:@"http://h.hiphotos.baidu.com/baike/w%3D268/sign=30b3fb747b310a55c424d9f28f444387/1e30e924b899a9018b8d3ab11f950a7b0308f5f9.jpg"];
    37         NSData *data=[NSData dataWithContentsOfURL:urlstr];
    38         UIImage *image=[UIImage imageWithData:data];
    39         //提示
    40         NSLog(@"图片加载完毕");
    41         
    42         //4.回到主线程,展示图片
    43         [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
    44     });
    45 }
    46 
    47 @end

    显示效果:

    打印结果:

    要求使用GCD的方式,在子线程加载图片完毕后,主线程拿到加载的image刷新UI界面。

     1 //
     2 //  YYViewController.m
     3 //  14-GCD基本使用(下载图片)
     4 //
     5 //  Created by 孔医己 on 14-6-25.
     6 //  Copyright (c) 2014年 itcast. All rights reserved.
     7 //
     8 
     9 #import "YYViewController.h"
    10 
    11 @interface YYViewController ()
    12 @property (weak, nonatomic) IBOutlet UIImageView *imageView;
    13 
    14 @end
    15 
    16 @implementation YYViewController
    17 
    18 - (void)viewDidLoad
    19 {
    20     [super viewDidLoad];
    21     
    22 }
    23 
    24 //当手指触摸屏幕的时候,从网络上下载一张图片到控制器的view上显示
    25 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    26 {
    27     
    28     //1.获取一个全局串行队列
    29     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    30     //2.把任务添加到队列中执行
    31     dispatch_async(queue, ^{
    32         
    33         //打印当前线程
    34         NSLog(@"%@",[NSThread currentThread]);
    35       //3.从网络上下载图片
    36         NSURL *urlstr=[NSURL URLWithString:@"http://h.hiphotos.baidu.com/baike/w%3D268/sign=30b3fb747b310a55c424d9f28f444387/1e30e924b899a9018b8d3ab11f950a7b0308f5f9.jpg"];
    37         NSData *data=[NSData dataWithContentsOfURL:urlstr];
    38         UIImage *image=[UIImage imageWithData:data];
    39         //提示
    40         NSLog(@"图片加载完毕");
    41         
    42         //4.回到主线程,展示图片
    43 //        [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
    44         dispatch_async(dispatch_get_main_queue(), ^{
    45             self.imageView.image=image;
    46             //打印当前线程
    47             NSLog(@"%@",[NSThread currentThread]);
    48         });
    49     });
    50 }
    51 
    52 @end

    打印结果:

    好处:子线程中得所有数据都可以直接拿到主线程中使用,更加的方便和直观。

    三、线程间通信

    从子线程回到主线程

    dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // 执⾏耗时的异步操作...
    dispatch_async(dispatch_get_main_queue(), ^{
    
    // 回到主线程,执⾏UI刷新操作
    });
    });  
  • 相关阅读:
    Atitit sql计划任务与查询优化器统计信息模块
    Atitit  数据库的事件机制触发器与定时任务attilax总结
    Atitit 图像处理知识点体系知识图谱 路线图attilax总结 v4 qcb.xlsx
    Atitit 图像处理 深刻理解梯度原理计算.v1 qc8
    Atiti 数据库系统原理 与数据库方面的书籍 attilax总结 v3 .docx
    Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析
    Atitit View事件分发机制
    Atitit 基于sql编程语言的oo面向对象大规模应用解决方案attilax总结
    Atitti 存储引擎支持的国内点与特性attilax总结
    Atitit 深入理解软件的本质 attilax总结 软件三原则"三次原则"是DRY原则和YAGNI原则的折
  • 原文地址:https://www.cnblogs.com/wendingding/p/3807265.html
Copyright © 2011-2022 走看看