multiple return values in callback blocks

645 Views Asked by At

people I am working with don't wanna use delegate methods for a couple of reasons and they want me to come up with a solution;

basically they want a callback block with multiple return values, and when the first return value arrived block should still wait for the upcoming return values

something like

[parserobject parsefile:file withCallback {
                if (started) {
                    //file parsing started 
                    //this should get executed first
                }
                //if file parsing succesfully started also check if it 
                //succesfully finished or failed in the same callback
                if (finished) {
                    //file parsing finished 
                }

                if(failed)
                {
                    //this represents if parsing failed any time from start to finish
                    //if so exit the callback

                }
            }];

I have seen people using structs or nsintegers to return different values but usually only one result is returned....

is that above code block possible to written in objective-c?

2

There are 2 best solutions below

2
On BEST ANSWER

This is your function

typedef void(^VOIDCALLBACK)(void); //Just a type here
typedef void(^BOLLCALLBACK)(bool succeed);//Just a type here
-(void)parserobjectWithFile:(NSString *)file StartCallBack:(VOIDCALLBACK) startCallBack completionBlock:(BOLLCALLBACK) completion{
    // When start
 dispatch_async(dispatch_get_main_queue(), ^{
     startCallBack();//Make call back run in main queue
   });
    //When finisehd set succeed to yes,otherwise set to no
    BOOL succeed = YES;//Pass in to indicator if succeed
  dispatch_async(dispatch_get_main_queue(), ^{
    completion(succeed); //Make call back run in main queue
});
}

Then you call it like this

   [self parserobjectWithFile:@""
             StartCallBack:^{
                 //Here task is start
             }
           completionBlock:^(bool succeed) {
                //Here task is done.Check succeed to figure out if succeed
           }];

A simple example

This is the function part

@implementation ViewController

-(void)viewDidAppear:(BOOL)animated{
 [self parserobjectWithFile:@"" StartCallBack:^{
  NSLog(@"start");
 } completionBlock:^(bool succeed) {
   NSLog(@"finished");
 }];
}


typedef void(^VOIDCALLBACK)(void); //Just a type here
typedef void(^BOLLCALLBACK)(bool succeed);//Just a type here
-(void)parserobjectWithFile:(NSString *)file StartCallBack:   (VOIDCALLBACK) startCallBack completionBlock:(BOLLCALLBACK) completion{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    //Start
    dispatch_async(dispatch_get_main_queue(), ^{
        startCallBack();//Make call back run in main queue
    });
    sleep(2.0);
    BOOL succeed = YES;//Pass in to indicator if succeed
    dispatch_async(dispatch_get_main_queue(), ^{
        completion(succeed); //Make call back run in main queue
    });
});    
}
@end

This will output

2015-06-11 23:39:25.426 OCTest[767:144615] start
2015-06-11 23:39:27.426 OCTest[767:144615] finished
0
On

It is possible to write a block that does different things depending on the state reached so far. In order for that to work, declare variables that represent block's state with the __block modifier:

__block BOOL started = NO;
__block BOOL finished = NO;
__block BOOL failed = NO;
[parserobject parsefile:file withCallback:^ {
    if (started) {
        //file parsing started 
        //this should get executed first
    } else {
        ...
        // Conditionally set started to YES
        started = YES;
    }
    //if file parsing succesfully started also check if it 
    //succesfully finished or failed in the same callback
    if (finished) {
        //file parsing finished 
    }
    if(failed) {
        //this represents if parsing failed any time from start to finish
        //if so exit the callback
    }
}];