1. 程式人生 > >iOS開發多線程篇—GCD的基本使用

iOS開發多線程篇—GCD的基本使用

@property 函數 特殊 sig 屏幕 select 獲取 nba ike

一、主隊列介紹

主隊列:是和主線程相關聯的隊列,主隊列是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刷新操作
});
});  

iOS開發多線程篇—GCD的基本使用