How to specify return types in GCD blocks

How can I specify 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 }); } 
+4
source share
4 answers
 - (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 format (parameters / return type) is indicated in the function signature. In this case, dispatch_sync uses a block with no return type and no parameters. If you want other variables to work with you, you need to declare them outside the block, as in the code above.

+8
source

Since the block shares the area with the parent, the easiest way is not to specify the return type at all. For instance:

 - (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 want to specify a return type, you cannot use dispatch_sync() , because it only accepts blocks without a return type. Example of using blocks manually:

 typedef NSData *(^MyDataBlock)(); MyDataBlock getData = ^ NSData *() { return [NSData data]; }; NSData *data = getData(); 

Please note that since in the second example you are not using dispatch_sync() , this code will be executed immediately in the current queue, and not wait until the processor time is available. Waiting for a processor to have some downtime may be faster than executing it immediately.

The advantage of this approach is much more flexible, you can pass the getData variable to other methods, etc., and they can even execute it inside their own dispatch_sync() call to take advantage of the GCD priority system.

+3
source

What exact error do you see? Since this line

 dispatch_sync(concurrentQueue, ^(NSData *)){ // here return type showing error 

has a syntax error. After the list of blocked arguments, you have stray ) .

Even if you fix it, you have another problem, which is that you are trying to return a value from the block passed to dispatch_sync() , and yet dispatch_sync() expects a block that returns void . It seems that what you are really trying to do is return the data from the function, but for this you need to pass the data from the block back to the external function. You can do this with __block -qualified variable, for example:

 - (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; } 
+1
source

To deploy Frioze a warning: if you call any API that is not recommended to be used in the main thread in the queue, you are _sync, and you call dispatch_sync from the main thread, you can also call this API from the main thread as you requested to wait for it to finish. This is true not only for the block in your _sync call, but also for any previous blocks sent via _async that are not yet complete.

0
source

Source: https://habr.com/ru/post/1384202/


All Articles