以下是我的拙見匠抗,如有不當之處,歡迎大家指正污抬!
一汞贸、在上一個網(wǎng)絡(luò)請求的完成回調(diào)中調(diào)用寫一個網(wǎng)絡(luò)請求
這是一個最普通的思路绳军,在上一個請求完成的回調(diào)中進行下一次的請求
二、利用NSOperation添加依賴操作和優(yōu)先級
這個方法主要利用NSOperation
的addDependency:
方法來添加依賴
/// 操作(模擬網(wǎng)絡(luò)請求)
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
[self network_request1];
}];
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
[self network_request2];
}];
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
[self network_request3];
}];
/// 添加依賴
[operation2 addDependency:operation1];
[operation3 addDependency:operation2];
/// 創(chuàng)建隊列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperations:@[operation1, operation2, operation3] waitUntilFinished:NO];
模擬網(wǎng)絡(luò)請求
#pragma mark - Network
- (void)network_request1 {
sleep(3);
NSLog(@"-------- network request 1");
}
- (void)network_request2 {
sleep(2);
NSLog(@"-------- network request 2");
}
- (void)network_request3 {
sleep(1);
NSLog(@"-------- network request 3");
}
三矢腻、Dispatch_group 組隊列
這個思路主要用到的方法有dispatch_group_enter
门驾、dispatch_group_leave
、dispatch_group_wait
多柑、dispatch_group_notify
在請求之前進入group
:“dispatch_group_enter
”
在請求之后離開group
:“dispatch_group_leave
”
group
內(nèi)的任務(wù)為當前任務(wù)奶是,所以這時候會卡住線程,等任務(wù)一執(zhí)行完畢竣灌,這個類似信號量“dispatch_group_wait
”
注意:dispatch_group_enter 和dispatch_group_leave 成對出現(xiàn)聂沙,且在真實的網(wǎng)絡(luò)請求環(huán)境中,請求成功或者失敗都要leave
/// 創(chuàng)建組隊列
self.group = dispatch_group_create();
/// 模擬網(wǎng)絡(luò)請求
[self network_request1];
[self network_request2];
[self network_request3];
/// group 中任務(wù)全部完成
dispatch_group_notify(self.group, dispatch_get_main_queue(), ^{
NSLog(@"請求完成");
});
模擬網(wǎng)絡(luò)請求
#pragma mark - Network
- (void)network_request1 {
/// 任務(wù)開始之前進入group
dispatch_group_enter(self.group);
sleep(3);
NSLog(@"-------- network request 1");
/// 任務(wù)完成,離開group,與 enter成對出現(xiàn)
dispatch_group_leave(self.group);
/// 現(xiàn)在 group 內(nèi)的任務(wù)為當前任務(wù)帐偎,所以這時候會卡住線程逐纬,等任務(wù)一執(zhí)行完畢蛔屹,這個類似信號量
/// 注意 dispatch_group_leave 和 dispatch_group_enter 不能在同一個線程削樊,不然會死鎖
dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER);
}
- (void)network_request2 {
/// 任務(wù)開始之前進入group
dispatch_group_enter(self.group);
sleep(2);
NSLog(@"-------- network request 2");
/// 任務(wù)完成,離開group,與 enter成對出現(xiàn)
dispatch_group_leave(self.group);
dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER);
}
- (void)network_request3 {
/// 任務(wù)開始之前進入group
dispatch_group_enter(self.group);
sleep(1);
NSLog(@"-------- network request 3");
/// 任務(wù)完成,離開group,與 enter成對出現(xiàn)
dispatch_group_leave(self.group);
dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER);
}
四、Dispatch_barrier 任務(wù)阻塞
主要方法dispatch_barrier_sync
和dispatch_barrier_async
相同點:都會等待方法之前的任務(wù)執(zhí)行完兔毒,再執(zhí)行方法后的任務(wù)
不同點:dispatch_barrier_sync
會等待自己的block中任務(wù)執(zhí)行完在執(zhí)行方法之后的任務(wù)漫贞,而dispatch_barrier_async
不會等待自己的任務(wù)結(jié)束,會繼續(xù)執(zhí)行后面的任務(wù)
/// 創(chuàng)建線程
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_sync(queue, ^{
[self network_request1];
});
/// 阻塞當前線程
dispatch_barrier_sync(queue, ^{
NSLog(@"第一個請求完成");
});
dispatch_sync(queue, ^{
[self network_request2];
});
dispatch_barrier_sync(queue, ^{
NSLog(@"第二個請求完成");
});
dispatch_sync(queue, ^{
[self network_request3];
});
dispatch_barrier_sync(queue, ^{
NSLog(@"第三個請求完成");
});
模擬網(wǎng)絡(luò)請求
#pragma mark - Network
- (void)network_request1 {
sleep(3);
NSLog(@"-------- network request 1");
}
- (void)network_request2 {
sleep(2);
NSLog(@"-------- network request 2");
}
- (void)network_request3 {
sleep(1);
NSLog(@"-------- network request 3");
}
五育叁、Dispatch_semaphore 信號量
主要方法:dispatch_semaphore_signal
迅脐、dispatch_semaphore_wait
當信號量為0則該函數(shù)就會一直等待,也就是不返回(相當于阻塞當前線程)豪嗽,dispatch_semaphore_signal
我理解為訂閱信號谴蔑,會使得信號量+1
,dispatch_semaphore_wait
會使信號量-1
龟梦。當信號量不大于0時隐锭,信號量-1
,同時后續(xù)代碼會繼續(xù)執(zhí)行计贰,但是當信號量等于0時钦睡,信號量不做減1動作,同時阻塞當前的執(zhí)行躁倒,在timeout之前遇到信號量大于0時荞怒,會繼續(xù)做-1
操作,并執(zhí)行后續(xù)任務(wù)秧秉。
/// 信號量 為 0褐桌,則該函數(shù)就會一直等待,也就是不返回(相當于阻塞當前線程)
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
/// 創(chuàng)建線程
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
[self network_request1];
/// 請求完成訂閱信號
dispatch_semaphore_signal(semaphore);
});
/// 等待信號
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_async(queue, ^{
[self network_request2];
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_async(queue, ^{
[self network_request3];
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
模擬網(wǎng)絡(luò)請求
#pragma mark - Network
- (void)network_request1 {
sleep(4);
NSLog(@"-------- network request 1");
}
- (void)network_request2 {
sleep(2);
NSLog(@"-------- network request 2");
}
- (void)network_request3 {
// sleep(1);
NSLog(@"-------- network request 3");
}