如何在GCD块中指定返回类型?在这里,我想将结果作为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
});
}
答案 0 :(得分:8)
- (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;
}
块的格式(参数/返回类型)在函数的签名中指定。在这种情况下,dispatch_sync
使用没有返回类型且没有参数的块。如果您想要使用更多变量,则需要在块外声明它们,如上面的代码所示。
答案 1 :(得分:4)
由于块与父级共享作用域,因此最简单的方法是不指定返回类型。例如:
- (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;
}
如果您确实要指定返回类型,则不能使用dispatch_sync()
,因为它只接受没有返回类型的块。如何手动使用块的示例是:
typedef NSData *(^MyDataBlock)();
MyDataBlock getData = ^ NSData *() {
return [NSData data];
};
NSData *data = getData();
请注意,因为在第二个示例中没有使用dispatch_sync()
,所以此代码将在当前队列上立即执行 ,而不是等到有一些可用的CPU时间。等待CPU有一些空闲时间实际上可能比立即执行它更快。
优点是这种方法更灵活,您可以将getData
变量传递给其他方法等等,甚至可以在自己的dispatch_sync()
调用中执行它以利用GCD的优先系统。
答案 2 :(得分:1)
您看到的确切错误是什么?因为这行
dispatch_sync(concurrentQueue, ^(NSData *)){ // here return type showing error
有语法错误。你的块参数列表后面有一个迷路)
。
即使你修复了这个问题,你还有另一个问题,那就是你试图从传递给dispatch_sync()
的块中返回一个值,而dispatch_sync()
期望一个块返回{{} 1}}。看来你真正要做的就是从函数中返回数据,但要做到这一点,你需要将块中的数据传递回外部函数。您可以使用void
限定变量执行此操作,如下所示:
__block
答案 3 :(得分:0)
要扩展Frioze的注意事项:如果你调用任何不推荐在队列主线程上使用的API,你要_sync到,并且从主线程调用dispatch_sync,你也可以从主线程调用该API因为你要求等待它完成。这不仅适用于_sync调用中的块,也适用于通过_async发送但尚未完成的任何先前块。