As apple's documentation says,
"Blocks are also used for callbacks, defining the code to be executed when a task completes."
So block should execute after the body of the function in which the block is passed executes. But I wrote the following test code:
void testBlock(void(^test)()){
NSLog(@"1");
};
int main(int argc, const char * argv[]) {
@autoreleasepool {
testBlock(^{
NSLog(@"2");
});
}
}
and the output is only "1".
So where's the NSLog(@"2")
?
@Julian Król But look at this function in AFNetworking:
- (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{
// completionBlock is manually nilled out in AFURLConnectionOperation to break the retain cycle.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-retain-cycles"
#pragma clang diagnostic ignored "-Wgnu"
self.completionBlock = ^{
if (self.completionGroup) {
dispatch_group_enter(self.completionGroup);
}
dispatch_async(http_request_operation_processing_queue(), ^{
if (self.error) {
if (failure) {
dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{
failure(self, self.error);
});
}
} else {
id responseObject = self.responseObject;
if (self.error) {
if (failure) {
dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{
failure(self, self.error);
});
}
} else {
if (success) {
dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{
success(self, responseObject);
});
}
}
}
if (self.completionGroup) {
dispatch_group_leave(self.completionGroup);
}
});
};
#pragma clang diagnostic pop
}
This function doesn't explicitly call the block and the block parameter doesn't even has a name so it seems that the block should not be executed. But as I use this function as following:
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFXMLParserResponseSerializer serializer];
operation.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"application/rss+xml"];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSXMLParser *XMLParser = (NSXMLParser *)responseObject;
[self.parserDictionary setObject:XMLParser forKey:urlString];
[XMLParser setShouldProcessNamespaces:YES];
XMLParser.delegate = self;
[XMLParser parse];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//When an error occurs while parsing.
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error Loading Data"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:@"Ok"
otherButtonTitles:nil];
[alertView show];
[MBProgressHUD hideHUDForView:self.tableView animated:YES];
}];
And the block is truly executed. What's is the reason here?