Reputation: 27399
I have an instance method that I'd like to invoke directly using the callback param from a block in objective-c. I prefer this approach when I need to do more than a simple 1 liner in the callback.
Here is the basic setup...
I init a class w/ some type of call back so I can parse json after the http request lets say
- (void)initFooAndDoStuff {
Foo *foo = [[Foo alloc] initWithCallback:^(NSData * response){
// do stuff
}];
}
//this is the instance method I'd like to invoke instead of an inline function
- (void)callBackWithHttpResponse:(NSData *)response {
// do stuff ... assuming it's more complex than a 1 liner that is
}
I can setup a call back that does something inline (but again more complex stuff would be better in a stand alone instance method perhaps)
Foo *foo = [[Foo alloc] initWithCallback:^(NSData * response){
NSLog(@"foo");
}];
I can use the instance method like below but it feels a little long winded. Any way I can cut this down (the syntax that is).
Foo *foo = [[Foo alloc] initWithCallback:^(NSData * response){
[self callBackWithHttpResponse:response];
}];
Upvotes: 0
Views: 561
Reputation: 17762
If you're going to put the implementation in a method, you might as well just have the method return the entire block:
-(void (^)(NSData *))httpResponseHandler {
return ^(NSData *responseData){
// do something with responseData
};
}
Then the places you use it would be a bit more succinct:
Foo *foo = [[Foo alloc] initWithCallback:[self httpResponseHandler]];
Upvotes: 2
Reputation: 162712
Foo *foo = [[Foo alloc] initWithCallback:^(NSData * response){
[self callBackWithHttpResponse:response];
}];
OK -- pretty darned readable as it is.
Now, go in the other room and hit yourself in the head 3 times with a brick to simulate not having looked at this project in 6 months to a year.
Now, read the code again.
Still readable, isn't it?
There is nothing wrong with a bit of verbosity when that verbosity says exactly what the code is doing. You could go with a target/action pattern as Ken Thomases suggested, but that would require additional complexity elsewhere.
Instead of callback
, I would change it to be even more specific. I.e. if the callback was really a completion handler:
Foo *foo = [[Foo alloc] initWithHTTPResponseCompletionHandler:^(NSData * response){
[self httpResponseCompletionHandler:response];
}];
Upvotes: 1