项目开发中的GCD实战应用

整理一下项目中GCD的应用

GCD是apple提供的一组C语言的API,主要用于实现一些特殊的功能,比如并发编程等,虽然是C语言的接口,但是经过block封装,调用十分方便,因此在项目中应用十分广泛,现在总结一下我个人在项目中的使用.

延迟执行

1
2
3
4
NSTimeInterval delayTime = 5;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayTime * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
/// do someting on main thread
});

快速创建单例

1
2
3
4
5
6
7
8
9
+ (instancetype)shareInstance
{
static id shareInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
shareInstance = [[self alloc] init];
});
return shareInstance;
}

异步执行代码

1
2
3
4
5
6
dispatch_sync(dispatch_get_global_queue(0, 0), ^{
// do something ,global queue
dispatch_sync(dispatch_get_main_queue(), ^{
// main thread
});
});

顺序执行代码(相当于使用NSOperationQueueDependency)

1,2,3同时执行,4最后打印

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
dispatch_group_t serviceGroup = dispatch_group_create();
   
    dispatch_group_enter(serviceGroup);
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"1---%@", [NSThread currentThread]);
        dispatch_group_leave(serviceGroup);
    });
   
    dispatch_group_enter(serviceGroup);
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"2---%@", [NSThread currentThread]);
        dispatch_group_leave(serviceGroup);
    });
   
    dispatch_group_enter(serviceGroup);
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"3---%@", [NSThread currentThread]);
        dispatch_group_leave(serviceGroup);
    });
   
    dispatch_group_notify(serviceGroup, dispatch_get_main_queue(), ^{
        NSLog(@"4----%@", [NSThread currentThread]);
    });

1,2异步执行完毕再异步执行3,4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
dispatch_queue_t barrierQueue = dispatch_queue_create("jiangdaohong.github.io", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(barrierQueue, ^(){
NSLog(@"1");
});
dispatch_async(barrierQueue, ^(){
NSLog(@"2");
});
dispatch_barrier_async(barrierQueue, ^(){
NSLog(@"dispatch_barrier_async test");
});
dispatch_async(barrierQueue, ^(){
NSLog(@"3");
});
dispatch_async(barrierQueue, ^(){
NSLog(@"4");
});

同步请求

由于NSURLSession没有提供同步请求,可以利用semaphore实现同步请求.

1
2
3
4
5
6
7
8
9
10
11
NSURLSession *session = [NSURLSession sharedSession];
// 创建信号
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// 设置信号量
dispatch_semaphore_signal(semaphore);
}];
[task resume];
// 等待
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

定时器(NSTimer不准)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//倒计时时间
__block int timeout = 60;
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
// 执行间隔1s
dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0),1.0 * NSEC_PER_SEC, 0);
dispatch_source_set_event_handler(timer, ^{
if(timeout <= 0){
// 倒计时结束,关闭
dispatch_source_cancel(timer);
dispatch_async(dispatch_get_main_queue(), ^{
// 主线程刷新UI
});
} else {
int minutes = timeout / 60;
int seconds = timeout % 60;
dispatch_async(dispatch_get_main_queue(), ^{
// 主线程刷新UI
});
timeout--;
}
});
dispatch_resume(timer);