How can i specify the return types in GCD blocks? Here I want to return my result as NSData
...
- (NSData *)returnData:(NSString *)urlString{
dispatch_queue_t concurrentQueue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_sync(concurrentQueue, ^{ // here return type showing error
NSString *strUrl = urlString;
if([strUrl length] == 0)
return nil; // from this point i want to stop the execution of the block and return nil .
// otherwise only continue the left operations
});
}
- (NSData *)returnData:(NSString *)urlString {
dispatch_queue_t concurrentQueue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// Declare your local data outside the block.
// `__block` specifies that the variable can be modified from within the block.
__block NSData *localData = nil;
dispatch_sync(concurrentQueue, ^{
// Do something with `localData`...
localData = somethingWonderful;
});
// `localData` now contains your wonderful data.
return localData;
}
The block's format (parameters/return type) are specified in the function's signature. In this case, dispatch_sync
uses a block with no return type and no parameters. If you want further variables to work with you need to declare them outside the block, as in the code above.
Since a block shares the scope with the parent, it's easiest not to specify a return type at all. For example:
- (NSData *)returnData:(NSString *)urlString{
dispatch_queue_t concurrentQueue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
__block NSData *data; // the __block keyword allows this variable to be changed by a block
dispatch_sync(concurrentQueue, ^(NSData *)){ // here return type showing error
data = [NSData dataWithContentsOfURL:@"http://stackoverflow.com"];
});
return data;
}
If you do want to specify a return type, then you cannot use dispatch_sync()
, because it only accepts blocks with no return type. An example of how to use blocks manually is:
typedef NSData *(^MyDataBlock)();
MyDataBlock getData = ^ NSData *() {
return [NSData data];
};
NSData *data = getData();
Note that because you are not using dispatch_sync()
in the second example this code will execute immediately on the current queue instead of waiting until there is some available CPU time. Waiting for the CPU have some idle time can actually be faster than executing it immediately.
The advantage is this approach is much more flexible, you can pass the getData
variable around to other methods and so on, and they could even execute it inside their own dispatch_sync()
call to take advantage of GCD's priority system.
What's the exact error you're seeing? Because this line
dispatch_sync(concurrentQueue, ^(NSData *)){ // here return type showing error
has a syntax error. You've got a stray )
after your block argument list.
Even if you fix that, you have another problem, which is that you're trying to return a value from a block passed to dispatch_sync()
, and yet dispatch_sync()
expects a block that returns void
. It seems that what you're really trying to do is return the data from the function, but to do this you need to pass the data from the block back to your outer function. You can do this with a __block
-qualified variable, like this:
- (NSData *)returnData:(NSString *)urlString{
dispatch_queue_t concurrentQueue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
__block NSData *localData = nil;
dispatch_sync(concurrentQueue, ^{
if ([urlString length] == 0) {
// we don't have any data to return
return; // localData is already nil
}
// calculate localData
localData = ...;
});
// Now localData should be populated
return localData;
}
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