私は完了ハンドラがどのように機能するかを尋ね、理解しようとしています。私はかなりの数を使用し、多くのチュートリアルを読みました。ここで使用するものを投稿しますが、他の人のコードを参考にせずに自分で作成できるようにしたいと考えています。
この呼び出し元メソッドのこの完了ハンドラーを理解しています:
-(void)viewDidLoad{
[newSimpleCounter countToTenThousandAndReturnCompletionBLock:^(BOOL completed){
if(completed){
NSLog(@"Ten Thousands Counts Finished");
}
}];
}
次に、呼び出されたメソッドで:
-(void)countToTenThousandAndReturnCompletionBLock:(void (^)(BOOL))completed{
int x = 1;
while (x < 10001) {
NSLog(@"%i", x);
x++;
}
completed(YES);
}
それから、私は多くのSO投稿に基づいてこれを思いつきました:
- (void)viewDidLoad{
[self.spinner startAnimating];
[SantiappsHelper fetchUsersWithCompletionHandler:^(NSArray *users) {
self.usersArray = users;
[self.tableView reloadData];
}];
}
このメソッドを呼び出した後、受信したデータ ユーザーでテーブルビューをリロードします。
typedef void (^Handler)(NSArray *users);
+(void)fetchUsersWithCompletionHandler:(Handler)handler {
NSURL *url = [NSURL URLWithString:@"http://www.somewebservice.com"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:10];
[request setHTTPMethod: @"GET"];
**// We dispatch a queue to the background to execute the synchronous NSURLRequest**
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
// Perform the request
NSURLResponse *response;
NSError *error = nil;
NSData *receivedData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
if (error) { **// If an error returns, log it, otherwise log the response**
// Deal with your error
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
NSLog(@"HTTP Error: %d %@", httpResponse.statusCode, error);
return;
}
NSLog(@"Error %@", error);
return;
}
**// So this line won't get processed until the response from the server is returned?**
NSString *responseString = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
NSArray *usersArray = [[NSArray alloc] init];
usersArray = [NSJSONSerialization JSONObjectWithData:[responseString dataUsingEncoding:NSASCIIStringEncoding] options:0 error:nil];
// Finally when a response is received and this line is reached, handler refers to the block passed into this called method...so it dispatches back to the main queue and returns the usersArray
if (handler){
dispatch_sync(dispatch_get_main_queue(), ^{
handler(usersArray);
});
}
});
}
カウンターの例では、呼び出されたメソッド (渡されたブロックを含む) が完了するまでループを終了しないことがわかります。したがって、「完了」部分は、実際には、渡されたブロックではなく、呼び出されたメソッド内のコードに依存しますか?
この場合、「完了」部分は、NSURLRequest への呼び出しが同期的であるという事実に依存します。非同期だったら?NSURLResponse によってデータが入力されるまで、ブロックの呼び出しを延期するにはどうすればよいでしょうか?