あなたは本質的に非同期メソッド、dataTaskWithRequest
を撮影した、それ同期(すなわち、それブロックが呼び出されたスレッド)作られています。セマフォのすべてを取り除く。それはとにかく、本当に悪いパターンです。
これは、ネットワークコールのデータをreturn
にしたかったためです。あなたはそうしてはいけません。完了ハンドラパターンを使用する必要があります。例えば
、のは、あなたのメソッドは、現在のように見える想像してみましょう:あなたはvoid
戻り値の型に変更し、そしてcompletionHandler
パラメータを追加する必要があります
- (id)performRequest:(NSURLRequest *)request {
__block id header;
manager.completionQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
} else {
header = responseObject;
}
dispatch_semaphore_signal(semaphore);
}];
[dataTask resume];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
return header;
}
:
- (void)performRequest:(NSURLRequest *)request completionHandler:(void (^)(id _Nullable responseObject, NSError * _Nullable error))completionHandler {
manager.completionQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
completionHandler(nil, error);
} else {
completionHandler(responseObject, nil);
}
}];
[dataTask resume];
}
そして、あなたそのように呼びます:
[self performRequest:request completionHandler:^(id responseObject, NSError *error) {
// use responseObject and error here
}];
// but not here
出典
2016-07-18 07:16:45
Rob
セマフォでメインスレッドをブロックしているようですね。 – holex