我试图了解完成处理程序和块。我相信你可以在没有完成处理程序的情况下将块用于许多深度编程,但我想我理解完成处理程序是基于块的。(所以基本上完成处理程序需要块,但不是相反)。
所以我在网上看到了这段关于旧推特框架的代码:
[twitterFeed performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if (!error) {
self.successLabel.text = @"Tweeted Successfully";
[self playTweetSound];
} else {
// Show alert
}
// Stop indicator
sharedApplication.networkActivityIndicatorVisible = NO;
}];
在这里,我们调用了一个方法,该方法执行操作(执行 TWRequest)并在完成 responseData & urlResponse & error 时返回。只有当它返回时,它才会执行测试授予的块并停止活动指示器。完美的!
现在这是我为另一个可以工作的应用程序设置的设置,但我正在尝试将这些部分组合在一起:
@interface
Define an ivar
typedef void (^Handler)(NSArray *users);
Declare the method
+(void)fetchUsersWithCompletionHandler:(Handler)handler;
@implementation
+(void)fetchUsersWithCompletionHandler:(Handler)handler {
//...Code to create NSURLRequest omitted...
__block NSArray *usersArray = [[NSArray alloc] init];
//A. Executes the request
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
// Peform the request
NSURLResponse *response;
NSError *error = nil;
NSData *receivedData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
// Deal with your error
if (error) {
}
NSLog(@"Error %@", error);
return;
}
// Else deal with data
NSString *responseString = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
usersArray = [NSJSONSerialization JSONObjectWithData:[responseString dataUsingEncoding:NSASCIIStringEncoding] options:0 error:nil];
// Checks for handler & returns usersArray to main thread - but where does handler come from & how does it know to wait tip usersArray is populated?
if (handler){
dispatch_sync(dispatch_get_main_queue(), ^{
handler(usersArray);
});
}
});
}
以下是我的理解:
- fetchUsersWithCompletionHandler 显然是 performRequestWithHandler 的同系物
- 不幸的是,这有点复杂,因为途中有一个 GCD 调用......
但基本上,执行请求并处理错误,处理数据,然后检查处理程序。我的问题是,这个处理程序部分是如何工作的?我知道如果它存在,那么它将发送回主队列并返回 usersArray。但是它怎么知道要等到 usersArray 被填充?我想让我感到困惑的是,在这种情况下,method:block 内部还有另一个块,即 dispatch_async 调用。我想我正在寻找的是真正做事情的逻辑,并且知道何时返回 responseData 和 urlResponse。我知道它不是同一个应用程序,但我看不到 performRequestWithHandler 的代码。