我發現這個線程作爲參考:How do I wait for an asynchronously dispatched block to finish?和我正在使用該代碼(發信號塊內的信號量)等待我的線程完成測試之前完成。信號量從未在單元測試信號(dispatch_get_main_que()從來沒有運行?)
但是我從來沒有信號燈的信號,它的做...所以我通過代碼加強,發現這個小片段中的代碼永遠不會運行:
dispatch_async(dispatch_get_main_queue(), ^{
[self removeDownloadSpinner];
block(callback);
});
是否dispatch_get_main_queue()不是當我單位解僱測試?如果不是,你如何單元測試異步塊?
編輯(這裏是更多的代碼): 基本上我有一個「ServerRequest」類,其中包含所有應用程序的傳入/傳出網絡請求。一種方法是這樣(完成塊typedeffed):
+(void)checkPlayerCode:(NSString *)playerCode completionHandler:(PlayerCompletionBlock)block {
[self addDownloadSpinner];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/players/%@",kBaseURL, playerCode]];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
[ServerConnectionRequest sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSDictionary *p = [data objectFromJSONData];
Player *player = [[Player alloc] init];
player.last_name = [p objectForKey:@"last_name"];
if (!error) {
dispatch_async(dispatch_get_main_queue(), ^{
[self removeDownloadSpinner];
block(player);
});
}
}];
}
這是從一個UIViewController稱爲像這樣:
[ServerRequest checkPlayerCode:codeCell.textField.text completionHandler:^(Player *p){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"wooo block" message:@"works" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil];
[alert show];
}];
然而dispatch_get_main_queue()塊永遠不會被解僱。
所以我在實際塊更多的代碼添加。是的,我的意思是我逐字逐句通過調試器。後臺線程關閉......但回調塊內部的中斷不會被觸發。也認爲這個問題可能是測試在主線程上運行;然而,我只是試圖在後臺線程上運行測試(gcd priority default),它仍然無法正常工作。我是否應該發佈我的測試? – Msencenb 2012-03-23 09:44:36
想我越來越近了。問題在於我的信號量鎖定了主線程,所以其他回調無法獲得線程。但是,如果我將semaphore_wait調用移入異步線程,則單元測試不會等待並完成。任何機會你可以給我一個單元測試的例子,它使用信號量等待而不阻塞主線程? – Msencenb 2012-03-23 09:52:12
對我沒有任何幫助。幾周前我做了一些信號量的代碼,然後重構了它。但正如你所說,你必須小心鎖定你正在執行的線程。正如我最近向其他人建議的那樣,請看看GCD和運營。對於您正在嘗試解決的較大問題,這可能是一個更容易,更好的答案。 – drekka 2012-03-23 13:41:59