在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