Reputation: 8977
What if I have a function that returns an int and the return value of the int is taken from the block?
For example:
- (int) queryForKey:(NSString *)aKey view:(UIButton *)aView countView:(UIView *)aCountView counter:(int) count {
//some initialization
[query countObjectsInBackgroundWithBlock:^(int number, NSError * error) {
[aCountView addSubview:self.generateCountLabel];
if (number > 0){
[aView setUserInteractionEnabled:YES];
[aView setEnabled:YES];
}
//return number; //doing this will generate an error
}];
}
also another question is, what if I have an int passed in as an argument of the function above and I would like to assign a value to it. Is some thing like that even possible?
Upvotes: 1
Views: 1429
Reputation: 6597
I've found a better solution. Hopefully this will help someone else who stumbles across the question. I would implement a solution to your code like so:
- (int) queryForKey:(NSString *)aKey view:(UIButton *)aView countView:(UIView *)aCountView counter:(int) count {
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
__block int number;
//some initialization
[query countObjectsInBackgroundWithBlock:^(int number, NSError * error) {
dispatch_async(queue, ^{
[aCountView addSubview:self.generateCountLabel];
if (number > 0){
[aView setUserInteractionEnabled:YES];
[aView setEnabled:YES];
}
dispatch_semaphore_signal(sema);
});
}];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
return number; //doing this will no longer generate an error
}
Then encapsulate your call with another dispatch_async so that your semaphore wait call doesn't block the main thread.
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{
[self queryForKey:@"AKey" view:myView countView:myCountView counter:aCounter];
});
Upvotes: -1
Reputation: 162722
The problem is that you have a synchronous method (one that wants to return the value immediately) that needs to return a value derived from an asynchronous method (one that goes about it's business in a different thread).
There are a couple of ways of fixing this:
wait for the countObjectsInBackgroundWithBlock: method to complete, use the __block
pattern as @simonpie described.
replace the return number;
with a call to something somewhere interested in the resulting number. This also means that queryForKey:view:countView:
will likely return void
.
The latter is the preferred solution as it will not block the thread calling the queryForKey:...
method.
Note that you can't diddle UIKit classes on anything but the main thread. If that block is executed on a background thread, then doing what you are doing in the block is invalid.
Upvotes: 1
Reputation: 354
Well your block does not have a return value, it returns void.
To return a value you could use the __block
modifier on a variable outside your block and store then answer there which can then be used by the rest of your method (or code).
Upvotes: 1