信号量
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
dispatch_semaphore_signal(sem);
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
例子1
-(void)dispatch_group_function1
{
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_queue_create("com.dispatch.test", DISPATCH_QUEUE_CONCURRENT), ^{
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.baidu.com"]];
NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// 请求完成,可以通知界面刷新界面等操作
NSLog(@"第一步网络请求完成");
// 使信号的信号量+1,这里的信号量本来为0,+1信号量为1(绿灯)
dispatch_semaphore_signal(semaphore);
}];
[task resume];
// 以下还要进行一些其他的耗时操作
NSLog(@"耗时操作继续进行");
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
});
dispatch_group_async(group, dispatch_queue_create("com.dispatch.test", DISPATCH_QUEUE_CONCURRENT), ^{
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.github.com"]];
NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// 请求完成,可以通知界面刷新界面等操作
NSLog(@"第二步网络请求完成");
// 使信号的信号量+1,这里的信号量本来为0,+1信号量为1(绿灯)
dispatch_semaphore_signal(semaphore);
}];
[task resume];
// 以下还要进行一些其他的耗时操作
NSLog(@"耗时操作继续进行");
dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"刷新界面等在主线程的操作");
});
}
控制最多并发数
- (void)semaphore
{
// 1.创建一个信号量 ,且设置同时操作的并发数为5
dispatch_semaphore_t semaphore = dispatch_semaphore_create(5);
// 2.创建100个任务
for (int i = 0; i < 100; i++) {
// 3.当信号量大于0时即可往下执行, 同时将信号量-1
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
// 4.异步执行任务
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
// 5.信号通知,即让信号量+1
dispatch_semaphore_signal(semaphore);
NSLog(@"当前是:%d任务并且在%@线程上",i,[NSThread currentThread]);
});
}
group
dispatch_group_t downloadGroup = dispatch_group_create();
dispatch_group_enter(downloadGroup);
dispatch_group_leave(downloadGroup);
dispatch_group_notify(downloadGroup, dispatch_get_main_queue(), ^{
});
延迟
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 2.0 秒后异步追加任务代码到主队列,并开始执行
NSLog(@"after---%@",[NSThread currentThread]); // 打印当前线程
});
单例
- (void)once {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 只执行 1 次的代码(这里面默认是线程安全的)
});
}