ferson2020
ferson2020

Reputation: 3315

How do I combine blocks and methods returning values in iOS?

I'm new to blocks in iOS, and I'm trying to figure out the correct way to use them. Here's my setup:

I have a method foo which returns whether an operation (RKObjectRequestOperation) succeeded or not. I provide the operation with a block for success and a block for failure, so in the success block I want foo to return YES, and in the failure block I want foo to return NO.

For example:

- (BOOL) foo {
    RKObjectRequestOperation *request = [[RKObjectRequestOperation alloc] initWithRequest:urlRequest responseDescriptors:responseDescriptors];

    [request setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
        NSLog(@"Success!");
        // return YES?
    } failure:^(RKObjectRequestOperation *operation , NSError *error) {
        NSLog(@"Failure!");
        // return NO?
    }];

    [request start];
}

However, as far as I know, a block is only able to return its own value; it cannot cause the method which is calling it to return. Is this correct? If this is the case, the only thing I can think of is to have foo take another block as a parameter which is called on success or on failure of the operation. The problem with this is that going up the call stack from 'foo`, I would have to change any method with a return type to return void and accept a block as a parameter to call instead. It seems excessive to have to change all of those methods. Am I missing something conceptually?

Upvotes: 0

Views: 1017

Answers (1)

Lily Ballard
Lily Ballard

Reputation: 185671

What you're missing is the fact that this block is (presumably1) called asynchronously. It's a completion block, so it's not fired until the requested operation is complete, which is a concurrent operation. So by the time the block has fired, your -foo method has already returned to its caller, and has probably made it all the way back to the runloop and has started doing other stuff.

Basically, this means that you can't return anything from -foo based on the block, because the block hasn't fired yet. You'll need to redesign your -foo method to be asynchronous itself.

1I'm not familiar with RKObjectRequestOperation but completion blocks only make sense in an asynchronous context.

Upvotes: 7

Related Questions