Reputation: 14527
I have a value that I'm retrieving from a block that I'd like to return in the below method. Being that it appears the block is asynchronous, how can I accomplish this?
-(UIImage*) imageAtIndex:(NSUInteger)index
{
UIImage *image;
[self.album enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:index] options:0 usingBlock: ^(ALAsset *result, NSUInteger index, BOOL *stop)
{
//set image in here
}];
return image;
}
Upvotes: 4
Views: 457
Reputation: 23278
I had done it like this in the past, check it.
-(void) imageAtIndex:(NSUInteger)index //since block is async you may not be able to return the image from this method
{
UIImage *image;
[self.album enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:index] options:0 usingBlock: ^(ALAsset *result, NSUInteger index, BOOL *stop)
{
//set image in here
dispatch_async(dispatch_get_main_queue(), ^{ //if UI operations are done using this image, it is better to be in the main queue, or else you may not need the main queue.
[self passImage:image]; //do the rest of the things in `passImage:` method
});
}];
}
Upvotes: 2
Reputation: 912
If your block is asynchronous, you are not able to set the returned value before you return is, as the program may not have completed the asynchronous task before the method ends. A few better solutions would be:
If you so desire, find a synchronous method which does the same job.
Now this might not be the best choice, as your UI would lock up while the block is running.
Call a selector when the value is found, and make the method itself void.
Perchance, try something like this:
-(void) findImageAtIndex:(NSUInteger)index target:(id)target foundSelector:(SEL)foundSEL
{
__block UIImage *image;
[self.album enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:index] options:0 usingBlock: ^(ALAsset *result, NSUInteger index, BOOL *stop)
{
//set image in here
if ([target respondsToSelector:foundSEL]) { //If the object we were given can call the given selector, call it here
[target performSelector:foundSEL withObject:image];
return;
}
}];
//Don't return a value
}
Then you could call it like this:
...
//Move all your post-finding code to bar:
[self findImageAtIndex:foo target:self foundSelector:@selector(bar:)];
}
- (void)bar:(UIImage *)foundImage {
//Continue where you left off earlier
...
}
Upvotes: 2