2015-02-12 73 views
2

這是我第一次使用dispatch_group_t,我犯了一個簡單的錯誤。 dispatch_group_notify在任何異步調用返回之前都會被調用,因此在第一個調用dispatch_group_leave(group)之前,調用EXC_BAD_INSTRUCTIONdispatch_group_t - EXC_BAD_INSTRUCTION

但是,我不知道爲什麼會發生這種情況。

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, ^{ 
    [self getCategoriesMainWithParameters:nil withSuccess:^(NSArray *objects) { 
     [categoriesMain addObjectsFromArray:objects]; 
     dispatch_group_leave(group); 
    } failure:^(NSError *error) { 
     groupError = error; 
     dispatch_group_leave(group); 
    }]; 
}); 

dispatch_group_async(group, queue, ^{ 
    [self getCategoriesSubWithParameters:nil withSuccess:^(NSArray *objects) { 
     [categoriesSub addObjectsFromArray:objects]; 
     dispatch_group_leave(group); 
    } failure:^(NSError *error) { 
     groupError = error; 
     dispatch_group_leave(group); 
    }]; 
}); 

dispatch_group_async(group, queue, ^{ 
    [self getCategoriesProductWithParameters:nil withSuccess:^(NSArray *objects) { 
     [categoriesProduct addObjectsFromArray:objects]; 
     dispatch_group_leave(group); 
    } failure:^(NSError *error) { 
     groupError = error; 
     dispatch_group_leave(group); 
    }]; 
}); 

dispatch_group_notify(group,dispatch_get_main_queue(),^{ 
    ... 
}); 
+0

見http://stackoverflow.com/a/25433076/629118我解釋了 「引擎蓋下」。 – 2015-02-12 01:57:08

回答

2

功能dispatch_group_async自動進入當塊被調度的基團,並且留下當所述調度塊的回報。當塊本身調用異步方法時,這不起作用。

正如您正確識別的那樣,在處理異步方法時,您必須手動輸入和離開組。但是,不應該使用dispatch_group_async來輸入組(因爲它會在調度的塊返回時自動離開組),而是在調用異步方法之前手動調用dispatch_group_enter,然後像完成處理程序那樣調用dispatch_group_leave。當每個「輸入」與「離開」相匹配時,該組將被通知。

因此,它可能看起來像:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
dispatch_group_t group = dispatch_group_create(); 

dispatch_group_enter(group); 
[self getCategoriesMainWithParameters:nil withSuccess:^(NSArray *objects) { 
    [categoriesMain addObjectsFromArray:objects]; 
    dispatch_group_leave(group); 
} failure:^(NSError *error) { 
    groupError = error; 
    dispatch_group_leave(group); 
}]; 

dispatch_group_enter(group); 
[self getCategoriesSubWithParameters:nil withSuccess:^(NSArray *objects) { 
    [categoriesSub addObjectsFromArray:objects]; 
    dispatch_group_leave(group); 
} failure:^(NSError *error) { 
    groupError = error; 
    dispatch_group_leave(group); 
}]; 

dispatch_group_enter(group); 
[self getCategoriesProductWithParameters:nil withSuccess:^(NSArray *objects) { 
    [categoriesProduct addObjectsFromArray:objects]; 
    dispatch_group_leave(group); 
} failure:^(NSError *error) { 
    groupError = error; 
    dispatch_group_leave(group); 
}]; 

dispatch_group_notify(group,dispatch_get_main_queue(),^{ 
    ... 
});