我們?cè)贏PP開發(fā)過程中, 很多情況下會(huì)碰到多個(gè)網(wǎng)絡(luò)請(qǐng)求同時(shí)存在的要求, 這對(duì)我們開發(fā)者來說一般會(huì)有網(wǎng)絡(luò)請(qǐng)求之間是否存在依賴關(guān)系, 即:上個(gè)網(wǎng)絡(luò)請(qǐng)求結(jié)果有沒有可能影響到下一個(gè); 這就是計(jì)算機(jī)發(fā)展中的并發(fā)問題; 由于是筆者不是計(jì)算機(jī)專業(yè)畢業(yè)的學(xué)生, 所以對(duì)這些不是很了解, 經(jīng)查閱資料后,將所得記錄如下.
引用國外大神來區(qū)分并發(fā)與并存的區(qū)別的一張圖并發(fā)是指至少兩個(gè)Action可以同時(shí)存在, 并行至少兩個(gè)Action可以同時(shí)run

并發(fā)初了解
在過去單核CPU時(shí)代, 碰到并發(fā)問題的時(shí)候, 處理方式是多個(gè)線程不斷交替換入換出內(nèi)存(上圖), 給你一種并發(fā)已經(jīng)解決的錯(cuò)覺, 而現(xiàn)代多核CPU時(shí)代, 每一個(gè)線程都可以占用一個(gè)核心(下圖), 這個(gè)就是并行解決.
實(shí)際運(yùn)用
我們?cè)陂_發(fā)的過程中可能會(huì)碰到一個(gè)界面多個(gè)網(wǎng)絡(luò)請(qǐng)求的需求情況;
此時(shí)要考慮這幾個(gè)請(qǐng)求之間的關(guān)系, 是不是有相互依賴的關(guān)系
一. 多個(gè)網(wǎng)路請(qǐng)求彼此依賴
方式之一采用GCD
dispatch_group_t結(jié)合信號(hào)量dispatch_semaphore_t(或者采用外部變量bool或者數(shù)字來記錄)來實(shí)現(xiàn)
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_async(group, queue, ^{
dispatch_semaphore_wait(semphore, DISPATCH_TIME_FOREVER);
NSLog(@"__1");
dispatch_semaphore_signal(semphore);
// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1* NSEC_PER_SEC)), queue, ^{
// NSLog(@"1");
// dispatch_semaphore_signal(semphore);
// });
});
dispatch_group_async(group, queue, ^{
dispatch_semaphore_wait(semphore, DISPATCH_TIME_FOREVER);
NSLog(@"__2");
dispatch_semaphore_signal(semphore);
});
dispatch_group_notify(group, queue, ^{
// dispatch_semaphore_wait(semphore, DISPATCH_TIME_FOREVER);
});
方式之二采用線程池
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSBlockOperation * bolckOperation = [NSBlockOperation blockOperationWithBlock:^{
for (NSInteger i = 0; i<2; i++) {
NSLog(@"%ld__%@", i, [NSThread currentThread]);
}
}];
NSBlockOperation * blcokA = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"我是AAAA");
}];
// 添加依賴 blcokA需要在bolckOperation操作完成之后才能進(jìn)行
[blcokA addDependency:bolckOperation];
[queue addOperation:bolckOperation];
[queue addOperation:blcokA];
NSOperationQueue是apple封裝GCD的一個(gè)新的管理線程的api, 很簡(jiǎn)單很強(qiáng)大, 而GCD則是封裝C的, 簡(jiǎn)單的多線程建議使用GCD, 復(fù)雜點(diǎn)的使用NSOperationQueue
這里想提一下信號(hào)量這個(gè)概念dispatch_semaphore_t跟信號(hào)量相關(guān)的函數(shù)只有三個(gè)dispatch_semaphore_create(long value), dispatch_semaphore_signal(semphore), dispatch_semaphore_wait(semphore, DISPATCH_TIME_FOREVER)/DISPATCH_TIME_NOW, 其中dispatch_semaphore_wait與dispatch_semaphore_signal成對(duì)出現(xiàn), signal是發(fā)射信號(hào), 信號(hào)量加一; wait是接受信號(hào), 信號(hào)量減一.
多個(gè)網(wǎng)絡(luò)請(qǐng)求完成后, 集中更新UI
這里采用的是dispatch_group_t
// 創(chuàng)建信號(hào)量
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
// 創(chuàng)建全局并行
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
dispatch_semaphore_signal(semaphore);
NSLog(@"yue");
});
dispatch_group_async(group, queue, ^{
dispatch_semaphore_signal(semaphore);
NSLog(@"duihuan11");
});
dispatch_group_async(group, queue, ^{
dispatch_semaphore_signal(semaphore);
});
dispatch_group_notify(group, queue, ^{
// 三個(gè)請(qǐng)求對(duì)應(yīng)三次信號(hào)等待
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
//在這里 進(jìn)行請(qǐng)求后的方法,回到主線程
dispatch_async(dispatch_get_main_queue(), ^{
//更新UI操作
NSLog(@"value: %@", semaphore);
});
});
在線程池中取消依賴關(guān)系, 可以滿足需求
代碼地址:Demo
PS: 日積月累, 天天進(jìn)步!
--END--