我有一个方法可以构建一个包,将其发送到 Web 服务,取回一个包,打开它并返回一个 nsdictionary。如何在后台队列中调用它以便在请求数据时显示 HUD?
3 回答
你可以像下面这样分离一个新线程
- (void) fetchData
{
//Show Hud
//Start thread
[NSThread detachNewThreadSelector:@selector(getDataThreaded)
toTarget:self
withObject:nil];
}
- (void) getDataThreaded
{
//Start Fetching data
//Hide hud from main UI thread
dispatch_async(dispatch_get_main_queue(), ^{
//Update UI if you have to
//Hide Hud
});
}
大中央调度 (gcd) 为您提出的要求提供了极大的支持。使用 gcd 在后台运行一些东西很简单:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_NORMAL, 0) ^{
NSDictionary* data = [self fetchAndParseData];
dispatch_async(dispatch_get_main_queue(), ^{
[self dataRetrieved:data];
});
});
此调用将立即返回(因此您的 UI 将继续响应)并dataRetrieved
在数据准备好时调用。
现在,根据 fetchAndParse 数据的工作方式,它可能需要更复杂一些。如果您使用 NSURLConnection 或类似的东西,您可能需要创建一个 NSRunLoop 来处理 gcd 线程上的数据回调。NSURLConnection 在大多数情况下无论如何都是异步的(尽管像 didReceiveData 这样的回调将通过 UI 线程进行路由),因此您只能在检索到所有数据后使用 gcd 来解析数据。这取决于您想要的异步程度。
除了之前的回复,为什么不用NSOperation
andNSOperationQueue
类呢?这些类是 GCD 下的抽象,使用起来非常简单。
我喜欢NSOperation
类,因为它允许在我通常开发的应用程序中模块化代码。
要设置一个NSOperation
,你可以像这样子类化它
//.h
@interface MyOperation : NSOperation
@end
//.m
@implementation MyOperation()
// override the main method to perform the operation in a different thread...
- (void)main
{
// long running operation here...
}
现在在主线程中,您可以将该操作提供给队列,如下所示:
MyOperation *op = [[MyOperation alloc] initWithDocument:[self document]];
[[self someQueue] addOperation:op];
PS 你不能在main
a 的方法中启动异步操作NSOperation
。完成main
后,将不会调用与该操作关联的委托。说实话,你可以,但这涉及到处理运行循环或并发行为。
这里有一些关于如何使用它们的链接。
- http://www.cimgf.com/2008/02/16/cocoa-tutorial-nsoperation-and-nsoperationqueue/
- https://developer.apple.com/cocoa/managingconcurrency.html
显然是类参考NSOperation