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

1、主隊列介紹網絡

主隊列:是和主線程相關聯的隊列,主隊列是GCD自帶的一種特殊的串行隊列,放在主隊列中得任務,都會放到主線程中執行。
提示:若是把任務放到主隊列中進行處理,那麼不論處理函數是異步的仍是同步的都不會開啓新的線程。
獲取主隊列的方式:

 dispatch_queue_t queue=dispatch_get_main_queue();異步

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

複製代碼
 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)使用同步函數,在主線程中執行主隊列中得任務,會發生死循環,任務沒法往下執行。示意圖以下:post

2、基本使用atom

1.問題  url

任務1和任務2是在主線程執行仍是子線程執行,仍是單獨再開啓一個新的線程?spa

複製代碼
 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.開啓子線程,加載圖片code

複製代碼
 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
複製代碼

打印結果:

好處:子線程中得全部數據均可以直接拿到主線程中使用,更加的方便和直觀。

 

3、線程間通訊

從子線程回到主線程

複製代碼
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 執⾏耗時的異步操做...
dispatch_async(dispatch_get_main_queue(), ^{

// 回到主線程,執⾏UI刷新操做
});
});  
相關文章
相關標籤/搜索