• iOS开发多线程篇 07 —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刷新操作
    });
    });  
  • 相关阅读:
    二叉树后序遍历
    [编程题] 赛马
    [编程题] 糖果谜题 C++实现输入未知个整数
    [编程题] 时钟
    [编程题] 会话列表
    A Fast Lock-Free Queue for C++
    Design Hangman
    Design a URL shortener [转]
    ostream 和 ostringsteam 的区别
    Hash Table Collision Handling
  • 原文地址:https://www.cnblogs.com/LiLihongqiang/p/5620957.html
Copyright © 2020-2023  润新知