如何在GCD块中指定返回类型

时间:2011-12-01 20:35:14

标签: objective-c ios ios4 objective-c-blocks grand-central-dispatch

如何在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



    });         
}

4 个答案:

答案 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发送但尚未完成的任何先前块。

相关问题