iOS開發(fā)多線程篇—GCD的基本使用

一、主隊列介紹

主隊列:是和主線程相關(guān)聯(lián)的隊列,主隊列是GCD自帶的一種特殊的串行隊列,放在主隊列中得任務(wù),都會放到主線程中執(zhí)行。

提示:如果把任務(wù)放到主隊列中進(jìn)行處理,那么不論處理函數(shù)是異步的還是同步的都不會開啟新的線程。

獲取主隊列的方式:

dispatch_queue_t?queue=dispatch_get_main_queue();

(1)使用異步函數(shù)執(zhí)行主隊列中得任務(wù),代碼示例:

//

//? YYViewController.m

//? 12-GCD的基本使用(主隊列)

//

//? Created by 孔醫(yī)己 on 14-6-25.

//? Copyright (c) 2014年 itcast. All rights reserved.

//

#import "YYViewController.h"

@interface YYViewController ()

@end

@implementation YYViewController

- (void)viewDidLoad

{

[super viewDidLoad];

//打印主線程

NSLog(@"打印主線程--%@", [NSThread mainThread]);

//1.獲取主隊列

dispatch_queue_t queue=dispatch_get_main_queue();

//2.把任務(wù)添加到主隊列中執(zhí)行

dispatch_async(queue, ^{

NSLog(@"使用異步函數(shù)執(zhí)行主隊列中的任務(wù)1--%@",[NSThread currentThread]);

});

dispatch_async(queue, ^{

NSLog(@"使用異步函數(shù)執(zhí)行主隊列中的任務(wù)2--%@",[NSThread currentThread]);

});

dispatch_async(queue, ^{

NSLog(@"使用異步函數(shù)執(zhí)行主隊列中的任務(wù)3--%@",[NSThread currentThread]);

});

}

@end

執(zhí)行效果:

(2)使用同步函數(shù),在主線程中執(zhí)行主隊列中得任務(wù),會發(fā)生死循環(huán),任務(wù)無法往下執(zhí)行。示意圖如下:

二、基本使用

1.問題

任務(wù)1和任務(wù)2是在主線程執(zhí)行還是子線程執(zhí)行,還是單獨再開啟一個新的線程?

//

//? YYViewController.m

//? 13-GCD基本使用(問題)

//

//? Created by 孔醫(yī)己 on 14-6-25.

//? Copyright (c) 2014年 itcast. All rights reserved.

//

#import "YYViewController.h"

@interface YYViewController ()

@end

@implementation YYViewController

- (void)viewDidLoad

{

[super viewDidLoad];

//開啟一個后臺線程,調(diào)用執(zhí)行test方法

[self performSelectorInBackground:@selector(test) withObject:nil];

}

-(void)test

{

NSLog(@"當(dāng)前線程---%@",[NSThread currentThread]);

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

//異步函數(shù)

dispatch_async(queue, ^{

NSLog(@"任務(wù)1所在的線程----%@",[NSThread currentThread]);

});

//同步函數(shù)

dispatch_sync(queue, ^{

NSLog(@"任務(wù)2所在的線程----%@",[NSThread currentThread]);

});

}

@end

打印結(jié)果:

2.開啟子線程,加載圖片

//

//? YYViewController.m

//? 14-GCD基本使用(下載圖片)

//

//? Created by 孔醫(yī)己 on 14-6-25.

//? Copyright (c) 2014年 itcast. All rights reserved.

//

#import "YYViewController.h"

@interface YYViewController ()

@property (weak, nonatomic) IBOutlet UIImageView *imageView;

@end

@implementation YYViewController

- (void)viewDidLoad

{

[super viewDidLoad];

}

//當(dāng)手指觸摸屏幕的時候,從網(wǎng)絡(luò)上下載一張圖片到控制器的view上顯示

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

//1.獲取一個全局串行隊列

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

//2.把任務(wù)添加到隊列中執(zhí)行

dispatch_async(queue, ^{

//打印當(dāng)前線程

NSLog(@"%@",[NSThread currentThread]);

//3.從網(wǎng)絡(luò)上下載圖片

NSURL *urlstr=[NSURL URLWithString:@"http://h.hiphotos.baidu.com/baike/w%3D268/sign=30b3fb747b310a55c424d9f28f444387/1e30e924b899a9018b8d3ab11f950a7b0308f5f9.jpg"];

NSData *data=[NSData dataWithContentsOfURL:urlstr];

UIImage *image=[UIImage imageWithData:data];

//提示

NSLog(@"圖片加載完畢");

//4.回到主線程,展示圖片

[self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];

});

}

@end

顯示效果:

打印結(jié)果:

要求使用GCD的方式,在子線程加載圖片完畢后,主線程拿到加載的image刷新UI界面。

//

//? YYViewController.m

//? 14-GCD基本使用(下載圖片)

//

//? Created by 孔醫(yī)己 on 14-6-25.

//? Copyright (c) 2014年 itcast. All rights reserved.

//

#import "YYViewController.h"

@interface YYViewController ()

@property (weak, nonatomic) IBOutlet UIImageView *imageView;

@end

@implementation YYViewController

- (void)viewDidLoad

{

[super viewDidLoad];

}

//當(dāng)手指觸摸屏幕的時候,從網(wǎng)絡(luò)上下載一張圖片到控制器的view上顯示

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

//1.獲取一個全局串行隊列

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

//2.把任務(wù)添加到隊列中執(zhí)行

dispatch_async(queue, ^{

//打印當(dāng)前線程

NSLog(@"%@",[NSThread currentThread]);

//3.從網(wǎng)絡(luò)上下載圖片

NSURL *urlstr=[NSURL URLWithString:@"http://h.hiphotos.baidu.com/baike/w%3D268/sign=30b3fb747b310a55c424d9f28f444387/1e30e924b899a9018b8d3ab11f950a7b0308f5f9.jpg"];

NSData *data=[NSData dataWithContentsOfURL:urlstr];

UIImage *image=[UIImage imageWithData:data];

//提示

NSLog(@"圖片加載完畢");

//4.回到主線程,展示圖片

//? ? ? ? [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];

dispatch_async(dispatch_get_main_queue(), ^{

self.imageView.image=image;

//打印當(dāng)前線程

NSLog(@"%@",[NSThread currentThread]);

});

});

}

@end

打印結(jié)果:

好處:子線程中得所有數(shù)據(jù)都可以直接拿到主線程中使用,更加的方便和直觀。

三、線程間通信

從子線程回到主線程

dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

// 執(zhí)?耗時的異步操作...

dispatch_async(dispatch_get_main_queue(), ^{

// 回到主線程,執(zhí)?UI刷新操作

});

});

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容