I hate blocks. They are meant to make the code more concise, but I couldn't find anything more ugly. For instance, with AFNetworking:
AFJSONRequestOperation* operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
requestsuccess:^(NSURLRequest *request, NSURLResponse *response, id JSON) {
// Some
// very
// long
// (and as ugly as blocks)
// processing
}
failure:^(NSURLRequest *request, NSURLResponse *response, NSError *error, id JSON )) {
// Failure code
}]
Something like this would have been much better:
AFJSONRequestOperation* operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
requestsuccess:@selector(requestSuccess:response:json:)
failure:@selector(requestSuccess:response:error:)]
So, is it possible to use method's selectors as blocks ? If not, how can I make the block code better ?
It annoys me, as these blocks seems to be the future of objective-c programming and they are just NOT readable.
So you think the block construct makes the code harder to read? I think they can sometimes make things easier to understand, especially in asynchronous contexts like in networking code.
To make it easier to read you can assign blocks to variables. (Indeed blocks are objective-c objects.)
Example:
typedef void(^SuccessBlock)(NSURLRequest *request, NSURLResponse *response, id JSON);
SuccessBlock successBlock = ^(NSURLRequest *request, NSURLResponse *response, id JSON) {
// code block
};
AFJSONRequestOperation* operation;
operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
success:successBlock
failure:nil];
You can also call a single handler method inside the block to keep it small.
Short blocks are good, overly long ones not, where you draw the line is of course a personal preference...
Using a method for a block is not hard (the other way around is more of a challenge). The simplest approach if you wish to use a method:
- (void) requestSuccess:(NSURLRequest *)request
response:(NSURLResponse *)response
json:(id)JSON
{
// Some
// very
// long
// (and as ugly as blocks)
// processing
}
- (void) requestFailure:(NSURLRequest *)request
response:(NSURLResponse *)response
error:(NSError **)error
json:(id)JSON
{
// Failure code
}
...
AFJSONRequestOperation* operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
requestsuccess:^(NSURLRequest *request, NSURLResponse *response, id JSON)
{
[self requestSuccess:request response:response json:JSON];
}
failure:^(NSURLRequest *request, NSURLResponse *response, NSError *error, id JSON ))
{
[self requestFailure:request response:response error:error json:JSON];
}]
You could go further with macros, or even performSelector
/NSInvocation
fun - whether it is worth it is up to you.
You can also move the blocks definitions before the call itself, along the lines of:
var = block;
[object method:var];
Which approach you choose is a matter of style.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With