最近做了一個需求虎眨,針對一批數(shù)據(jù),進行網(wǎng)絡請求镶摘,請求結束后嗽桩,根據(jù)返回結果,更新數(shù)據(jù)庫.
這種情況肯定是利用事務,批量更新比較合理凄敢。
同時網(wǎng)絡請求封裝是異步執(zhí)行碌冶,結果在回調(diào)里處理。這個時候GCD就派上用場了涝缝。
Dispatch Group機制這個使用法參照 《編寫高質(zhì)量iOS與OS X代碼的52個有效方法》--第六章 第44條
44.通過Dispatch Group機制扑庞,根據(jù)系統(tǒng)資源狀況來執(zhí)行任務
dispatch group
NSMutableArray * realnameOrderInfoModelArray = [[NSMutableArray alloc]init];
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
[self.successPrintInfoArray enumerateObjectsUsingBlock:^(YDOrderInfoModel * orderModel, NSUInteger idx, BOOL * _Nonnull stop) {
dispatch_group_enter(group);
dispatch_group_async(group, queue, ^{
YDRealnameOrderInfoModel * realnameOrderInfoModel = [[YDRealnameOrderInfoModel alloc] initWithOrderInfoModel:orderModel];
[YDUploadRealNameDataService uploadNewRealNameInfoWithDataArr:@[realnameOrderInfoModel] Success:^(BOOL result) {
if(result)
{
realnameOrderInfoModel.isUpload = @"1";
}
else
{
realnameOrderInfoModel.isUpload = @"-1";
}
[realnameOrderInfoModelArray addObject:realnameOrderInfoModel];
dispatch_group_leave(group);
} failure:^(NSString *error) {
[realnameOrderInfoModelArray addObject:realnameOrderInfoModel];
dispatch_group_leave(group);
}];
});
}];
dispatch_group_notify(group, dispatch_get_main_queue(), ^(){
//等數(shù)據(jù)處理完了再進行入庫.
[[YDOrderTool sharedOrderTool] addNewRealNameOrderDataWithArray:realnameOrderInfoModelArray];
});
NSOperationQueue
// 創(chuàng)建隊列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 任務1
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
UIImage * image =[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:self.url]]];
NSLog(@"任務1 完成譬重,線程:%@", [NSThread currentThread]);
}];
// 任務2
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
UIImage * image =[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:self.url1]]];
NSLog(@"任務2 完成,線程:%@", [NSThread currentThread]);
}];
// 任務3
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
UIImage * image =[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:self.url1]]];
NSLog(@"任務3 完成罐氨,線程:%@", [NSThread currentThread]);
}];
// 添加操作依賴臀规,注意不能循環(huán)依賴
[op1 addDependency:op2];
[op3 addDependency:op1];
op3.completionBlock = ^{
NSLog(@"全部完成,線程:%@", [NSThread currentThread]);
};
// 添加操作到隊列
[queue addOperation:op1];
[queue addOperation:op2];
[queue addOperation:op3];
其實操作隊列只是提供了一套高層的OC API栅隐。這里需要需要注意
The receiver is not considered ready to execute until all of its dependent operations have finished executing. If the receiver is already executing its task, adding dependencies has no practical effect. This method may change the isReady and dependencies properties of the receiver. It is a programmer error to create any circular dependencies among a set of operations. Doing so can cause a deadlock among the operations and may freeze your program.
1.循環(huán)依賴項會導致操作之間的死鎖塔嬉。
2.直到接收方的所有相關操作都完成后,才認為接收方已經(jīng)準備好執(zhí)行租悄。如果接收方已經(jīng)在執(zhí)行其任務谨究,那么添加依賴項沒有實際效果
NSOperation和NSOperationQueue相關
dispatch_semaphore
思路有點類似dispatch_group_enter來添加計數(shù)
{
dispatch_group_t group = dispatch_group_create();
for(int i = 0 ; i< 10; i ++)
{
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:self.url1] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
dispatch_semaphore_signal(semaphore);
}];
[task resume];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
});
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
NSLog(@"全部完成,線程:%@", [NSThread currentThread]);
}
其實用dispatch_group_wait 與 dispatch_group_notify來執(zhí)行后面的操作都可以泣棋,但是dispatch_group_notify可以直接將要執(zhí)行的動作傳入塊里胶哲。等dispatch_group執(zhí)行完后 會在執(zhí)行線程執(zhí)行。 加入當前線程不想堵塞潭辈,而開發(fā)者又想在任務結束之后得到通知鸯屿,dispatch_group_notify就更方便了。
iOS GCD之dispatch_semaphore學習