我需要在应用程序中进行多个异步服务调用:来自我的应用程序委托的didFinishLaunchingWithOptions:方法,以便从我的应用程序中的各个控制器中使用的服务中检索一些数据。我已经控制了服务,并且我已经将API设计为尽可能的REST,所以我需要在应用程序初始化期间进行多次调用。
我想要做的是显示一个带有进度指示器的加载视图 - 类似于Default.png中的默认启动画面 - 并在服务调用完成后删除该视图并且我有我需要的初始值。如果只有一个服务调用,这很容易做到,因为我可以通过隐藏加载视图并显示根控制器,将该逻辑挂钩到connectionDidFinishLoading:NSURLConnection的委托方法。
但是,通过多次服务调用,它变得棘手。我可以将所有内容“链接”起来并触发一个请求,等待它完成/失败,然后触发第二个请求,依此类推,直到我到达最后一个请求。在最后一个请求中,我然后隐藏加载视图并显示普通视图。但是,这可能会因多次服务调用而变得难以处理,并且代码变得难以理解和遵循。
有关最佳方法的任何建议吗?
我认为一个解决方案是让一个单独的类负责进行服务调用和应用程序初始化。单例对象将在启动时并行触发所有必要的请求,每个失败/结束回调将检查每个请求是否已完成。如果所有请求都已完成,那么它可以调用应用程序委托中的某个方法并告诉它隐藏加载视图,显示根控制器等。
思想?
答案 0 :(得分:0)
另一种可能性是让每个服务完成回调通知(NSNotification)进度指示器的控制器已经进行了进展。您还可以告诉控制器进度指示器,指出您计划进行多少次请求,并让它保持得分,并在它认为一切都完成时自己进行回调。
答案 1 :(得分:0)
我正在做类似NSOperationQueue
的事情,配置为一次只运行1个操作。请参阅示例WeaveEngine.m及其synchronizewithServer:credentials:
方法。我将所有单独的操作排队,这些操作主要是异步网络调用。
答案 2 :(得分:0)
您可以使用NSThreading并在单独的线程中为您需要的每件事进行同步调用
[NSThread detachNewThreadSelector:@selector(getDataRequest1:) toTarget:self withObject:urlRequest];
[NSThread detachNewThreadSelector:@selector(getDataRequest2:) toTarget:self withObject:urlRequest];
[NSThread detachNewThreadSelector:@selector(getDataRequest3:) toTarget:self withObject:urlRequest];
然后在每个线程的选择器中执行类似
的操作- (void) getDataRequest1:(NSURLRequest*)urlRequest {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSHTTPURLResponse *urlResponse;
NSError *error;
NSData *responseData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&urlResponse error:&error];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
if ([urlResponse statusCode] < 200 || [urlResponse statusCode] > 299) {
//request probably failed
}else{
[self performSelectorOnMainThread:@selector(completeRequest1:) withObject:responseData waitUntilDone:NO];
}
[pool drain];
[responseString release];
[urlRequest release];
}
当然这取决于你想要产生多少请求/线程。 你需要跟踪你产生的数量和完成的数量,这样你才能正确地阻止你的旋转器。