將任務添加到隊列,而且指定執行任務的函數程序員
//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 值響應
}
複製代碼