我有一个方法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....
});
答案 0 :(得分:4)
dataWithContentsOfURL仅适用于文件URL,而不适用于Web URL。它不是异步的。即使你使用GCD将它发送到自己的线程,也不是正确的方法。
如果您需要访问网络,则需要使用NSURLConnection。
使用+(void)sendAsynchronousRequest:(NSURLRequest *)请求队列:(NSOperationQueue )队列completionHandler:(void(^)(NSURLResponse ,NSData *,NSError *))处理程序
您最初处于正确的轨道上 - 您不希望该方法返回值。让完成处理程序块使用您收到的数据设置属性(ivar),并按照您的建议,在块的末尾使用通知来提醒您已完成。该通知可以触发访问该属性的方法,您可以获取数据对象。
答案 1 :(得分: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
- 脏调试工具,但NSURLConnection
是正确的方法。从iOS 5.0的+sendAsynchronousRequest:queue:completionHandler:
开始,使用它并不是那么难。