zoukankan      html  css  js  c++  java
  • IOS中的多线程之GCD

      在ios中,使用多线程有三种方式,分别是:NSThread、NSOperation和NSOperationQueue、GCD,在本节,主要讲解一下CDD的使用。

      GCD(Grand Central Dispatch) ,他是基于C语言开发的一套多线程开发机制,也是目前苹果官方推荐的多线程开发方法。GCD的抽象层次最高,用起来比较简单,但是因为它是基于C语言开发的,是面向过程的,所以在使用的时候不如面向对象的好理解。但是GCD这种机制相比较于前面两种多线程开发方式最显著的优点就是它对于多核运算更加有效。

    GCD队列

      GCD中也有一个类似于NSOperationQueue的队列,GCD统一管理整个队列中的任务,GCD中的队列分为三种:

    (1)     串行队列 dispatch_queue_create(, ):只有一个线程,加入到队列中的操作按添加顺序依次执行。

    (2)     全局队列dispatch_get_global_queue(,):有多个线程,操作进来之后它会将这些队列安排在可用的处理器上,同时保证先进来的任务优先处理。

    (3)     主队列 dispatch_get_main_queue():用来执行主线程上的操作任务。

    GCD使用

      从网络加载图片会使用多线程的方式,在这里,使用GCD的方式从网络获取图片。

      使用GCD取数据的时候有同步dispatch_sync(,)和异步dispatch_async(,)两种方式,一般会选择使用异步的方式请求数据。

      此外,如果是一组图片,可以选择使用串行队列请求显示,也就是按照顺序依次显示;还可以使用全局队列请求显示,显示的时候是异步并发,不按顺序随机显示。在下面的代码中,分别介绍一下两种方式。

    代码

    //  ViewController.m
    //  GCD_Demo
    //
    //  Created by jerei on 15-11-13.
    //  Copyright (c) 2015年 jerehedu. All rights reserved.
    //
    
    #import "ViewController.h"
    #define IMG_VIEW_WIDTH 90
    #define IMG_VIEW_HEIGHT 45
    #define GAP (([UIScreen mainScreen].bounds.size.width - (2*IMG_VIEW_WIDTH))/3.0)
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
     
        //设置界面上显示图片的imageView
        [self addImageViews];
        
        //加按钮
        [self addBtns];
    }
    
    #pragma mark - 设置界面上显示图片的imageView
    -(void)addImageViews{
        
        for (int i=0; i<10; i++) {
            UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(GAP+(i%2)*(IMG_VIEW_WIDTH+GAP), 60 + GAP + (i/2)*(IMG_VIEW_HEIGHT+20), IMG_VIEW_WIDTH, IMG_VIEW_HEIGHT)];
            imgView.tag = i+1;
            imgView.backgroundColor = [UIColor redColor];
            [self.view addSubview:imgView];
        }
    }
    
    #pragma mark - 按钮
    -(void)addBtns{
        UIButton *serial_btn = [[UIButton alloc] initWithFrame:CGRectMake(GAP, 30, IMG_VIEW_WIDTH, IMG_VIEW_HEIGHT)];
        [serial_btn setTitle:@"串行加载" forState:UIControlStateNormal];
        [serial_btn setBackgroundColor:[UIColor purpleColor]];
        [self.view addSubview:serial_btn];
        [serial_btn addTarget:self action:@selector(loadImage_gcd_serial) forControlEvents:UIControlEventTouchUpInside];
        
        UIButton *global_btn = [[UIButton alloc] initWithFrame:CGRectMake(2*GAP+IMG_VIEW_WIDTH, 30, IMG_VIEW_WIDTH, IMG_VIEW_HEIGHT)];
        [global_btn setTitle:@"并行加载" forState:UIControlStateNormal];
        [global_btn setBackgroundColor:[UIColor purpleColor]];
        [self.view addSubview:global_btn];
        [global_btn addTarget:self action:@selector(loadImage_gcd_global) forControlEvents:UIControlEventTouchUpInside];
    }
    
    #pragma mark - 从网络串行加载照片
    -(void)loadImage_gcd_serial{
        //串行队列
        dispatch_queue_t serialQueue = dispatch_queue_create("myThreadQueue1", DISPATCH_QUEUE_SERIAL);
        
        //请求图片
        for (int i=0; i<10; i++) {
            dispatch_async(serialQueue, ^{
                //从网络获取图片
                NSURL *url = [NSURL URLWithString:@"http://www.jerehedu.com/images/temp/logo.gif"];
                NSData *data = [NSData dataWithContentsOfURL:url];
                UIImage *image = [UIImage imageWithData:data];
                
                //回到主线程刷新界面
                dispatch_sync(dispatch_get_main_queue(), ^{
                    UIImageView *currentImgView = (UIImageView *)[self.view viewWithTag:i+1];
                    currentImgView.image = image;
                });
            });
        }
    }
    
    #pragma mark - 从网络并行加载照片
    -(void)loadImage_gcd_global{
        //并行队列
        dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        
        //请求图片
        for (int i=0; i<10; i++) {
            dispatch_async(globalQueue, ^{
                //从网络获取图片
                NSURL *url = [NSURL URLWithString:@"http://www.jerehedu.com/images/temp/logo.gif"];
                NSData *data = [NSData dataWithContentsOfURL:url];
                UIImage *image = [UIImage imageWithData:data];
                
                //回到主线程刷新界面
                dispatch_sync(dispatch_get_main_queue(), ^{
                    UIImageView *currentImgView = (UIImageView *)[self.view viewWithTag:i+1];
                    currentImgView.image = image;
                });
            });
        }
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
    }
    
    @end
    作者:杰瑞教育
    出处:http://www.cnblogs.com/jerehedu/ 
    版权声明:本文版权归杰瑞教育技有限公司和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    技术咨询:JRedu技术交流
     
  • 相关阅读:
    SpringBoot 配置提示功能
    【源码解析】凭什么?spring boot 一个 jar 就能开发 web 项目
    【源码解析】自动配置的这些细节都不知道,别说你会 springboot
    validator 自动化校验
    【spring-boot 源码解析】spring-boot 依赖管理梳理图
    js防抖节流
    koa2怎么自定义一个中间件
    nuxt 脚手架创建nuxt项目中不支持es6语法的解决方案
    vue中兄弟之间组件通信
    js中css样式兼容各个浏览器写法
  • 原文地址:https://www.cnblogs.com/jerehedu/p/5159372.html
Copyright © 2011-2022 走看看