How do I return a variable from a block inside a method?

Say I have this method that given a URL returns a UIImage:

- (void)getUIImageFromURL:(NSURL *)URL {
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];
    AFHTTPRequestOperation *imageOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    imageOperation.responseSerializer = [AFImageResponseSerializer serializer];

    [imageOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        return (UIImage *)responseObject;
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    }];

    [imageOperation start];
}

But it keeps giving me this error:

  • Where should I store 30+ UIColors for quick reference?
  • Simulate Launch Options
  • How can I add overlay text on a video, then re-encode it?
  • How to play youtube video using URL in AVPlayer IOS?
  • how to add animation to launch screen in iOS 9.3 using Objective c
  • XCTAssertEqual for custom objects in Swift
  • Incompatible block pointer types sending ‘UIImage *(^)(AFHTTPRequestOperation *__strong, _strong id)’ to parameter of type ‘void (^)(AFHTTPRequestOperation *_strong, __strong id)’

    I’m somewhat new to blocks, so perhaps I’m approaching this completely backwards. How best would I implement a method like this?

    3 Solutions Collect From Internet About “How do I return a variable from a block inside a method?”

    You cannot return an image from inside a block. This is an asynchronous API and cannot be used in the manner you are attempting to. Either use a blocking API, where the method is blocking until the image is downloaded (a bad solution), or implement support for the asynchronous API. For instance, pass a completion block to your getImage method and call it with in the completion block of the download operation. In this block, do what you need with the image.

    The callback block in setCompletionBlockWithSuccess: is a void block, you can’t change it’s return type.

    In your case, you would probably set the image inside of your block, instead of returning an image.

    [imageOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        self.myImage.image = [UIImage imageWithData:responseObject];
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    }];
    

    However, if you are dealing with AFNetworking and images, there are category methods that should greatly simplify retrieval and cacheing.

    [self.myImage setImagewithURL:URL];
    

    You are calling an asynchronous method with two blocks for handling success and failure. By the time one of these handlers is called, your calling method is long gone. It doesn’t make any sense to think you could return data to it, because it is gone.

    In the success block and failure block, you give instructions what to do when the operation has succeeded or failed. There is nobody there to return anything to. What you do is add code in the block to process and store the result of success in the right place, or to handle errors in the correct way.