iOS关于多线程常用方法汇总

Overview

前段时间整理了《Objective-C高级编程iOS与OS X 多线程和内存管理》中共的GCD相关的知识,其中内容大部分都是摘录书中的内容。

写完以后感觉有些意犹未尽,所以决定将在开发过程中常用的多线程的方法单独拿出来整理一下。

串行和并行

Objective-C

1
2
3
4
// 串行队列的创建方法
dispatch_queue_t serialDispatchQueue = dispatch_queue_create("com.example.gcd.serial", DISPATCH_QUEUE_SERIAL);
// 并发队列的创建方法
dispatch_queue_t concurrentDispatchQueue = dispatch_queue_create("com.example.gcd.concurrent", DISPATCH_QUEUE_CONCURRENT);

Swift

1
2
3
4
//串行队列的创建方法
let serialDispatch = DispatchQueue.init(label: "com.example.gcd.serial")
//并发队列的创建方法
let concurrentDispatchQueue = DispatchQueue.init(label: "com.example.gcd.concurrent", attributes: .concurrent)

同步和异步

Objective-C

1
2
3
4
5
6
7
dispatch_sync(serialDispatchQueue, ^{

});

dispatch_async(concurrentDispatchQueue, ^{

});

Swift

1
2
3
4
5
6
7
8
9
10
//同步
serialDispatch.sync {

}

//异步
concurrentDispatchQueue.async {

}

各种Dispatch Queue获取方法

Objective-C

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
* Main Dispatch Queue 的获取方法
*/
dispatch_queue_t mainDispatchQueue = dispatch_get_main_queue();

/*
* Global Dispatch Queue (高优先级)的获取方法
*/
dispatch_queue_t globalDispatchQueueHigh = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);

/*
* Global Dispatch Queue (默认优先级)的获取方法
*/
dispatch_queue_t globalDispatchQueueDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

/*
* Global Dispatch Queue (低优先级)的获取方法
*/
dispatch_queue_t globalDispatchQueueLow = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);

/*
* Global Dispatch Queue (后台优先级)的获取方法
*/
dispatch_queue_t globalDispatchQueueBackground = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);

Swift

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* --- 各种 Dispatch Queue的获取方法 --- */
/*
* 相应参数说明:
* label : 队列的标识
* qos(服务质量): .default 默认 .background 后台 .unspecified 不指定 .userInitiated 用户发起
attributes: 不指定的情况下是串行队列 .concurrent 并行队列
* autoreleaseFrequency: 自动释放的频率 .inherit 继承 .workItem工作组 .never 从不
* let dispatchQueue = DispatchQueue.init(label: String, qos: DispatchQoS, attributes: DispatchQueue.Attributes, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency, target: DispatchQueue?)
*/

/*
* Main Dispatch Queue 的获取方法
*/
let mainDispatchQueue = DispatchQueue.main

线程暂停和恢复

Objective-C

1
2
3
4
5
6
7
8
9
10
dispatch_queue_t queue = dispatch_queue_create("com.example.gcd.suspend", DISPATCH_QUEUE_CONCURRENT);
dispatch_suspend(queue);
dispatch_async(queue, ^{
dispatch_apply(5, queue, ^(size_t index) {
NSLog(@"---%ld---1----",index);
});
});
sleep(1);
NSLog(@"---2---");
dispatch_resume(queue);

Swift

1
2
3
4
5
6
7
8
let queue = DispatchQueue.init(label: "com.example.gcd.suspend", attributes: .concurrent)
queue.suspend()
queue.async {
print("------1----")
}
sleep(1)
print("---2---")
queue.resume()

延迟操作

Objective-C

1
2
3
4
5
6
7
8
9
10
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"--- 延迟3秒后执行的操作 ---");
});

//或

dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.f * NSEC_PER_SEC));
dispatch_after(time, dispatch_get_main_queue(), ^{
NSLog(@"--- 延迟3秒后执行的操作 ---");
});

Swift

1
2
3
4
DispatchQueue.main.asyncAfter(deadline: DispatchTime.init(uptimeNanoseconds: 2)){
print("---延迟2秒执行---")
}
print("---1---")

队列组

Objective-C

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
dispatch_group_t dispatchGroup = dispatch_group_create();
dispatch_queue_t queue = dispatch_queue_create("com.example.gcd.queue", DISPATCH_QUEUE_CONCURRENT);

dispatch_group_async(dispatchGroup, queue, ^{
//接口1
sleep(2);
NSLog(@"---接口1---");
});

dispatch_group_async(dispatchGroup, queue, ^{
//接口2
sleep(1);
NSLog(@"---接口2---");
});

dispatch_group_notify(dispatchGroup, queue, ^{
//结束
NSLog(@"---结束---");
});

Swift

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let dispatchGroup = DispatchGroup.init()
let queue = DispatchQueue.init(label: "com.example.gcd.queue", attributes: .concurrent)

dispatchGroup.enter()
queue.async {
print("---1---")
sleep(1)
print("---2---")
dispatchGroup.leave()
}

dispatchGroup.notify(queue: queue){
print("---3---")
}

栅栏方法

Objective-C

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
dispatch_queue_t queue = dispatch_queue_create("com.example.gcd.barrier", DISPATCH_QUEUE_CONCURRENT);

dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"dispatch_async1");
});

dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:1];
NSLog(@"dispatch_async2");
});

//等待前面的任务执行完毕后自己才执行,后面的任务需等待它完成之后才执行
dispatch_barrier_async(queue, ^{
NSLog(@"dispatch_barrier_async");
[NSThread sleepForTimeInterval:4];
NSLog(@"四秒后:dispatch_barrier_async");
});

dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:1];
NSLog(@"dispatch_async3");
});

dispatch_async(queue, ^{
NSLog(@"dispatch_async4");
});

Swift

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
let queue = DispatchQueue.init(label: "com.example.gcd.barrier", attributes: .concurrent)
queue.async {
sleep(2)
print("dispatch_async1")
}

queue.async {
sleep(1)
print("dispatch_async2")
}

//等待前面的任务执行完毕后自己才执行,后面的任务需等待它完成之后才执行
queue.async(flags: .barrier){
sleep(4)
print("四秒后:dispatch_barrier_async")
}

queue.async {
sleep(1)
print("dispatch_async3")
}

queue.async {
print("dispatch_async4")
}

信号量

Objective-C

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

dispatch_async(dispatch_queue_create("com.example.gcd.queue", DISPATCH_QUEUE_CONCURRENT), ^{
sleep(2);
NSLog(@"---1---");
dispatch_semaphore_signal(semaphore);
});
// dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t) 1 * NSEC_PER_SEC);
long result = dispatch_semaphore_wait(semaphore, time);
if (result == 0) {
/*
* 由于Dispatch Semaphore 的计数值达到大于等于1
* 或者在待机中的指定时间内
* Dispatch Semaphore 的计数值达到大于等于1
*
* 可执行需要进行排他控制的处理
*/
NSLog(@"---2---");
}else{
/*
* 由于 Dispatch Semaphore 的计数值为0
* 因此再达到指定时间为止待机
*/
NSLog(@"---3---");
}

Swift

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    let semaphore = DispatchSemaphore.init(value: 0)

DispatchQueue.init(label: "com.example.gcd.queue",attributes: .concurrent).async {
sleep(2)
print("---1---")
semaphore.signal()
}
print("---2---")
// semaphore.wait()
let time = DispatchTime.init(uptimeNanoseconds: 1)
let result = semaphore.wait(timeout: time)

if result == DispatchTimeoutResult.success {
print("---3---")
}else{
print("---4---")
}