Search code examples
iosblockobjective-c-blocks

iOS return block value from method


How I can return variable "myDoub(for example=65)" out of method and out block ??

- (double)executeRequestUrlString:(NSString *)urlString withBlock:(double (^)(double myDoub))block {
    [NSURLConnection sendAsynchronousRequest:request
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *response,
                                               NSData *data,
                                               NSError *error) {
                                   if (!error){
                                      //data = 65; for example
                                       block(data);
                                   }
                               }];

    return block(data);  // ???????? This NOT work
}


- (void)viewDidLoad
{
    [super viewDidLoad];

    //
    .......
    //
    double myNewDouble =  [self executeRequestUrlString:fullUrlImage withBlock:^double(double myDoub) {
        return myDoub;
    }];

    // how i can get here variable "myDoub=65" ????

}

Solution

  • The fundamental issue is that the network request is running asynchronously (i.e. the value you want to "return" will simply not be available until well after the method returns), so you cannot use it like you've outlined. The only way you could do that is to make the request synchronous, which is a very bad idea.

    Instead, you should embrace the asynchronous pattern. Specifically don't try to use the double after executeRequestUrlString method (because you won't have retrieved the value by the time you get there), but rather use it solely within the context of the withBlock block. So, put all the code contingent on that double inside the block:

    - (void)executeRequestUrlString:(NSString *)urlString withBlock:(void (^)(double myDoub))block 
    {
        [NSURLConnection sendAsynchronousRequest:request
                                           queue:[NSOperationQueue mainQueue]
                               completionHandler:^(NSURLResponse *response,
                                                   NSData *data,
                                                   NSError *error) {
                                       if (!error){
                                           double val = ... // extract the double from the `data`, presumably
                                           block(val);
                                       }
                                   }];
    }    
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        //
        .......
        //
        [self executeRequestUrlString:fullUrlImage withBlock:^(double myDoub) {
            // put all of your code that requires `myDoub` in here
        }];
    
        // but because the above is running asynchronously, do not try to use `myDoub` here
    }