I believe my use case is fairly common, but I couldn't find any documentation that would make me 100% sure about what I am doing. Any pointer is appreciated.
At some point in my app, I begin to download an object. Afterwards, the user can click a button. If the object is done downloading, I want to execute some code. Otherwise I want to wait until the object is downloaded and execute the same piece of code. If the user does not click the button, I don't want to do anything. The downloaded object is lost.
My basic idea was to do something like this:
NSObject *myObj = nil;
- (void)download {
[self downloadObj:^(NSObject *obj){
myObj = obj;
}];
}
- (void)buttonClicked {
waitOrExecuteDirectly:^{
// Some code with myObj
}
}
Of course, the first problem is "how do I wait?"
So I tried with
- (void)buttonClicked {
if(myObj) {
// Some code
} else {
// Wait then do the exact same code
}
}
But I think the trickier problem is "what happens if the objects finishes downloading right after the "if" is calculated and before the "else" block is entered?".
I tried to encapsulate the download within an NSOperation and use the completionBlock property. But if the operation has already finished when I set the callback, the completionBlock is never called. I do not want to set the callback in the "download" method because the user might not click on the button.
Is there a built-in mechanism that allows me to give a completion callback to a task that will wait or execute directly depending on the task status? If not, what would be the best practice to do it by myself? Use a NSLock when setting and reading myObj?
Here is the code example:
- (void)download {
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
[self downloadObj:^(NSObject *obj){
myObj = obj;
dispatch_semaphore_signal(sema);
}];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
dispatch_release(sema);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With