问题
I have a method call (it's a call from AFNetworking):
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON)
{
NSLog(@"IP Address: %@", [JSON valueForKeyPath:@"origin"]);
} failure:^(NSURLRequest *request , NSURLResponse *response , NSError *error , id JSON)
{
NSLog(@"Failed: %@",[error localizedDescription]);
}];
and I'm trying to pull the sucess and failure blocks out into a separate variable, that I can later pass into the method. But I can't figure out how to declare the blocks as variables. I'm looking to do something like this:
IDontKnowWhatKindOfDataTypeGoesHere successBlock = ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON)
{
NSLog(@"IP Address: %@", [JSON valueForKeyPath:@"origin"]);
}
and the same for the failureBlock.
So then I'm looking to make the AFJSONRequestOperation
call like:
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:successBlock failure:failureBlock];
But I cant figure how what the data types of the successBlock and failureBlock should be.
This is more for organization I suppose. I have a lot of code in my successBlock and the autoformatting of Xcode pushes is all to the right side of the screen which is totally annoying. So if I can pull it out (which should be possible, right), then I can organize my code better.
Thanks!
回答1:
It's awkward until you get used to it. The variable name appears mixed in with the type...
void (^success)(NSURLRequest *, NSHTTPURLResponse *, id) = ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSLog(@"request is %@, response is %@ and json is %@", request, response, JSON);
};
The stack variable name in this case is success. You can now refer to it in subsequent expressions that take the same type, like ...
AFJSONRequestOperation *operation = [AFJSONRequestOperationJSONRequestOperationWithRequest:request
success:success];
You can also make a block an property, like this:
@property (copy, nonatomic) void (^success)(NSURLRequest *, NSHTTPURLResponse *, id);
And call it like this:
self.success(aRequest, aResponse, someJSON);
Remember to nil it out when you're done calling it, so the caller has less to worry about creating a retain cycle.
Edit: good suggestion in commentary about using typedef to make this easier on the eyes and fingers:
typedef void (^SuccesBlock)(NSURLRequest *, NSHTTPURLResponse *, id);
So the stack variable looks like this:
SuccessBlock success = ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSLog(@"request is %@, response is %@ and json is %@", request, response, JSON);
};
and the property looks like this:
@property (copy, nonatomic) SuccessBlock success;
来源:https://stackoverflow.com/questions/18220645/ios-passing-blocks-to-functions