将任务添加到队列,而且指定执行任务的函数程序员
//1.建立任务block
dispatch_block_t task = ^{
NSLog(@"要执行的任务");
};
//2.获取/建立队列
dispatch_queue_t getQueue = dispatch_get_global_queue(0, 0);
//3.调用同/异步函数
dispatch_async(getQueue, task);
复制代码
系统自动建立的队列安全
dispatch_get_main_queue();
dispatch_get_global_queue(0, 0)
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
若是在同步函数或者串行队列中再加入一个同步函数或者串行队列,就很容易形成死锁。bash
tips: 1.主队列相似于串行队列。 2.主线程执行任务,也是按照代码从上至下执行,因此主线程中也相似执行着同步函数。多线程
@interface Person : NSObject
+(instancetype)shareInstance;
@end
static Person *person = nil;
@implementation Person
+(instancetype)shareInstance{
static dispatch_once_t token;
if (person == nil) {
dispatch_once(&token, ^{
person = [[Person alloc]init];
});
}
return person;
}
+(instancetype)allocWithZone:(struct _NSZone *)zone{
return [self shareInstance];
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
- (id)mutableCopyWithZone:(NSZone *)zone
{
return self;
}
@end
复制代码
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"延迟执行");
});
复制代码
//创造信号量,设置并发数为2
dispatch_semaphore_t lock = dispatch_semaphore_create(2);
//信号量等待
dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
//信号量释放。
dispatch_semaphore_signal(lock);
复制代码
控制任务执行顺序
dispatch_barrier_async
:前面的任务执行完毕才会来到这里
dispatch_barrier_sync
:做用相同,可是这个会堵塞线程,影响后面的任务执行(不论任务是否在队列内)。
重点: 栅栏函数只能控制同一并发队列,且这条队列须要本身建立,不一样队列将没法生效。并发
// 建立并发队列
dispatch_queue_t concurrentQueue = dispatch_queue_create("myqueue", DISPATCH_QUEUE_CONCURRENT);
//异步函数一
dispatch_async(concurrentQueue, ^{
NSLog(@"任务一完成");
});
//异步函数二
dispatch_async(concurrentQueue, ^{
NSLog(@"任务二完成");
});
//栅栏函数
dispatch_barrier_async(concurrentQueue, ^{
NSLog(@"上面两个任务都完成了,总算轮到我了。");
});
NSLog(@"若是栅栏函数是异步的,我会先执行;但若是是同步的话,我就得在栅栏函数执行完后,才能执行");
复制代码
保证线程安全异步
dispatch_queue_t concurrentQueue = dispatch_queue_create("myQueen", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i<2000; i++) {
dispatch_async(concurrentQueue, ^{
NSString *imageName = [NSString stringWithFormat:@"%d.jpg", (i % 10)];
NSURL *url = [[NSBundle mainBundle] URLForResource:imageName withExtension:nil];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
//若是没有栅栏函数,会崩溃。
dispatch_barrier_async(concurrentQueue, ^{
[self.mArray addObject:image];
});
});
}
复制代码
控制任务执行顺序
dispatch_group_t group = dispatch_group_create
: 建立组
dispatch_queue_t queue = dispatch_group_async
: 进组任务
dispatch_group_notify
:进组任务执行完毕通知
dispatch_group_wait
:进组任务执行等待时间async
//建立调度组
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_queue_t queue1 = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_async(group, queue, ^{
NSLog(@"任务一");
});
dispatch_group_async(group, queue1, ^{
NSLog(@"任务二");
});
dispatch_group_notify(group, queue, ^{
NSLog(@"任务结束");
});
复制代码
dispatch_group_enter
:进组
dispatch_group_leave
:出组
调用enter跟leave须要注意,要一一对应。
enter 多于 leave 不会调用通知notify。
enter 少于 leave 就会奔溃。函数
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
dispatch_async(queue, ^{
NSLog(@"第一个走完了");
dispatch_group_leave(group);
});
dispatch_group_enter(group);
dispatch_async(queue, ^{
NSLog(@"第二个走完了");
dispatch_group_leave(group);
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"全部任务完成,能够更新UI");
});
复制代码
@property (nonatomic, strong) dispatch_source_t source;
@property (nonatomic, strong) dispatch_queue_t queue;
- (void)viewDidLoad {
[super viewDidLoad];
self.queue = dispatch_queue_create("myQueue", 0);
self.source = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, dispatch_get_main_queue());
dispatch_source_set_event_handler(self.source, ^{
NSUInteger value = dispatch_source_get_data(self.source); // 取回来值 1 响应式
NSLog(@"响应回来的值 === %lu",value);
});
//默认是挂起的,不resume就不执行
dispatch_resume(self.source);
}
//触发事件
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
dispatch_source_merge_data(self.source, 1); // source 值响应
}
复制代码