2

我有一个方法 fetchFromWeb,它返回一个对象。我想从 GCD 异步调用这个方法。有人可以解释我如何从异步调用的方法中捕获返回值吗?

或者,我应该设置对象值,然后设置某种通知,而不是显式地从此方法获取返回值吗?

这是我所拥有的,谢谢!

        dispatch_async(kBGQueue, ^{


            NSData *data = [NSData dataWithContentsOfURL:kURL];
            [self performSelectorOnMainThread:@selector(fetchFromWeb:) 
                                   withObject:data 
                                waitUntilDone:YES];

            //Need to get the return value from method fetchFromWeb in selector....

        });
4

2 回答 2

4

dataWithContentsOfURL 仅适用于文件 URL,不适用于 Web URL。它不是异步的。即使您使用 GCD 将其发送到自己的线程,也不是正确的方法。

如果你需要出去上网,你需要使用 NSURLConnection。

使用 + (void)sendAsynchronousRequest:(NSURLRequest *)request queue:(NSOperationQueue )queue completionHandler:(void (^)(NSURLResponse , NSData*, NSError*))handler

最初您走在正确的轨道上-您不​​希望该方法返回值。让完成处理程序块使用您收到的数据设置一个属性(ivar),并按照您的建议,在块的末尾使用通知来提醒您它已完成。该通知可以触发访问属性的方法,您可以获取数据对象。

于 2012-07-31T16:22:40.613 回答
2

不要使用performSelectorOnMainThread:withObject:waitUntilDone:,因为您无法从中获得回报。与主调度队列一起使用dispatch_sync,其效果与performSelectorOnMainThread:withObject:waitUntilDone:YES.

dispatch_async(kBGQueue, ^{

    NSData *data = [NSData dataWithContentsOfURL:kURL];

    __block id result = nil; // Use the correct type here.
    dispatch_sync(dispatch_get_main_queue(), ^{

        result = [self fetchFromWeb:data];
    });

    // Do something with result here.
});


编辑:我应该补充一点,正如 Jason Howlin 所指出的,你不应该dataWithContentsOfURL:在运输应用程序中使用。用作快速n--dirty 调试工具是可以的,但NSURLConnection它是正确的方法。从 iOS 5.0+sendAsynchronousRequest:queue:completionHandler:开始,使用起来并没有那么难。

于 2012-07-31T16:00:51.403 回答