Toran Billups
Toran Billups

Reputation: 27399

Can I reference an instance method when I declare a block in objective-c

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

Answers (2)

Christopher Pickslay
Christopher Pickslay

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

bbum
bbum

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

Related Questions