当某个dispatch_semaphore_t正处于dispatch_semaphore_wait的时候,释放这个dispatch_semaphore_t的引用(sema = nil),将会导致崩溃。
示例:
- (void)viewDidLoad {
[super viewDidLoad];
self.sema = dispatch_semaphore_create(0);
// 每隔1秒释放一个信号量
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
dispatch_semaphore_signal(self.sema);
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 模拟10个任务
for (NSInteger index = 1; index <= 10; ++ index) {
// 每个任务都需要等待到有信号量才能开始
dispatch_semaphore_wait(self.sema, DISPATCH_TIME_FOREVER);
NSLog(@"执行任务%@...", @(index));
}
// 全部任务执行完毕
[timer invalidate];
});
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSLog(@"touchesEnded");
// crash!
// 当某个dispatch_semaphore_t正处于dispatch_semaphore_wait的时候
// 释放这个dispatch_semaphore_t的引用,将会导致崩溃
self.sema = nil;
}
控制台:
2016-11-22 16:01:50.520 SemaDemo[2990:136781] 执行任务1...
2016-11-22 16:01:51.482 SemaDemo[2990:136781] 执行任务2...
2016-11-22 16:01:52.495 SemaDemo[2990:136781] 执行任务3...
2016-11-22 16:01:53.209 SemaDemo[2990:136725] touchesEnded
网友评论