好久沒寫文章了。。 忙碌的工作,一不小心就讓我把這個好習慣給拋棄了。 也是自己不夠毅力堅持吧。有人跟我說,寫這些文章沒什么意義,這些問題你解決過,你就會有很深的印象,下次如果遇到同樣的問題一定會立即反應出同樣的問題。我說我寫文的意義不是為了記錄這些問題的解決辦法,我寫文意義而是去分享,我樂于分享,當自己不斷成長的時候,偶爾會回頭看看自己的成長歷程,看著這些“腳印”我內心會無比開心,也會激勵我要踏實走好每一步,要不斷努力,不斷學習。
言歸正傳,先說說我自己問題。
我們App請求數據時大部分人都會選擇AFNetworking。使用AFN異步請求,請求的數據返回后,就刷新相關UI。那么如果某一個頁面有多個網絡請求,假設有三個請求,A、B、C,而且UI里的數據必須等到A、B、C全部完成后刷新后才正確。那么三個單純的AFN請求,已經很明顯不滿足我們的需求了。
解決辦法一
我就認為它是最簡單最快解決問題也是最“笨”方法吧(我第一次使用的就是該方法)。設一個全局變量,每次請求成功后該變量都+1,并且都檢查該變量的值是不是3。如果是的話就刷新頁面。偽代碼如下:
int temp = 0;
request A {
success {
temp++;
[self checkTemp];
}
}
request B {
success {
temp++;
[self checkTemp];
}
}
request C {
success {
temp++;
[self checkTemp];
}
}
checkTemp {
if (temp == 3){
refreshUI
}
}
解決辦法二
主題來了,使用信號量也同樣可以解決這樣的問題。直接上代碼。
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self requestA];
});
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self requestB];
});
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self requestC];
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
//刷新界面
});
- (void)requestA
{
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
[Request postWithURL:url params:params success:^(id response){
dispatch_semaphore_signal(sema);
//處理response
} failure:^(NSError *error) {
dispatch_semaphore_signal(sema);
//處理錯誤
}];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}
requestB和requestC同上。我這就不寫了。
//還有一種情況就是,如果最后一個網絡請求是依賴前面的所以請求
//這里需要這樣改一下
dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//刷新界面
});
上面requestA、requestB、requestC加了信號量同時使用GCD多線程的調度組后,他們也是異步執行,執行的先后順不會卡住主線程。當A、B、Crequest的信號量全部都釋放后,就會通知group_notify并執行其操作。
希望我的解決辦法能幫助到有這些相關需求的朋友。??