如何使程序在继续执行下一个命令之前等待asynchronousNSURLConnection完成?

我怎样才能让我的程序等待asynchronousNSURLConnection完成前去下一行的代码?

SetDelegate *sjd= [SetDelegate alloc]; NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:post delegate:sjd]; [connection start]; 

这是我如何开始连接,我处理委托收到的数据,但我想等待连接结束之前继续进行,主要是因为这是在for循环,它必须运行我的数据库中的每个元素。

我需要从手机数据库的数据到远程数据库,并在数据成功放入电话数据库中的数据被删除。 我正在浏览手机数据库中的每个元素,并开始一个连接,这就是为什么我不能看到循环中的下一个东西是如何完成的。 当谈到Objective-C编程时我是一个初学者,所以我不确定这是否正确或不这样做

使调用同步不是一个选项,因为它阻止了程序,我有一个应该显示的进度条。

你的问题有点奇怪 你不可能的限制了这个问题。 你不能有一行代码“等待”一个进程完成而不是阻塞某些东西,在这种情况下,无论循环运行在哪个线程中。

你可以使用同步调用,如果你想,它不会阻塞你的应用程序,它只会阻止它被执行的线程。 在你的例子中,你有一个不断获取远程数据的循环,你希望你的UI反映,直到完成。 但是你不希望你的用户界面被阻止。 这意味着,你的循环线程已经必须在后台线程,所以你可以随意做一个循环的同步调用,而不会阻塞你的UI线程。 如果循环在UI线程上,你需要改变它来做你想做的事情。

你也可以使用asynchronous连接来做到这一点。 在这种情况下,您的操作可能会实际完成更快的B / C,您可以同时进行多个请求。 如果你这样做,你的循环可以留在UI线程,你只需要跟踪所有的连接,所以当它们完成后,你可以通知相关的控制器的状态。 您需要iVars来跟踪加载状态,并在加载完成后使用协议或NSNotification进行通信。

编辑:添加背景线上的同步呼叫的示例

如果你只希望循环完成所有的请求完成,而不是阻止你的UI线程这里是一个简单的例子:

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // post an NSNotification that loading has started for (x = 0; x < numberOfRequests; x++) { // create the NSURLRequest for this loop iteration NSURLResponse *response = nil; NSError *error = nil; NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; // do something with the data, response, error, etc } // post an NSNotification that loading is finished }); 

无论对象需要显示加载状态,都应该观察并处理您在此处发布的通知。 循环将通过一个后台线程同步所有的请求,你的UI线程将被解锁和响应。 这不是唯一的方法,事实上,我会自己使用asynchronous连接,但这是一个简单的例子,如何得到你想要的。

如果你只是想知道什么时候完成,并且不关心任何数据,只需使用NSNotificationCenter发布通知并让你的视图订阅它。

代表 – 通知完成后

 -(void) connectionDidFinishLoading:(NSURLConnection*)connection { [[NSNotificationCenter defaultCenter] postNotificationName:@"NSURLConnectionDidFinish" object:nil]; } 

查看 – 添加观察者并在观察时运行一些代码

 -(void) viewDidLoad { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(yourCleanupMethod) name:@"NSURLConnectionDidFinish" object:nil]; } -(void) yourCleanupMethod { // finish up [[NSNotificationCenter defaultCenter] removeObserver:self]; } 

现在,如果你需要传递一个简单的对象作为数据,你可以尝试在你的通知中加载对象参数,如下所示:

 [[NSNotificationCenter defaultCenter] postNotificationName:@"NSURLConnectionDidFinish" object:yourDataObject]; 

然后改变你的看法和清理签名像这样:

 -(void) viewDidLoad { // Notice the addition to yourCleanupMethod [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(yourCleanupMethod:) name:@"NSURLConnectionDidFinish" object:nil]; } -(void) yourCleanupMethod:(NSNotification *)notif { // finish up id yourDataObject = [notif object]; [[NSNotificationCenter defaultCenter] removeObserver:self]; } 

现在我发现自己需要的东西比这更多,所以我最终创build了一个单例来处理我的所有请求。 由于NSURLConnectionDelegate所有委托方法都为特定连接提供了NSURLConnection实例,因此可以简单地将可变数据对象存储在字典中,并且每次都通过连接查找它。 从那里我有一个方法签名,采取和对象和select器中,我与连接关联,所以在所有事情已经结束后,我可以通过对该对象执行该select器传递该可变数据对象到请求者。

我不会在这里包含所有的代码,但也许这会帮助你考虑什么是可能的。 我发现我有很多的代码绑在做web服务调用,所以把所有东西都包装在一个单例中给了我一个很好的获取数据的干净的方法。 希望这可以帮助!

如果你真的想等待,为什么要使用asynchronous调用呢? 改用同步呼叫:

 NSURLResponse* response = nil; NSData* data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:nil] 

这种方法将阻止它被执行的线程,所以你应该确保你想要做到这一点! 我提到它会阻止吗? 🙂

你说你想等待一个asynchronous调用来完成,所以我假设你正在调用你在一个单独的线程中发布的代码。

我build议看看新的sendAsynchronourRequest方法。 我已经公布了一个例子,你可以把它包装在一个类中 ,当连接完成/超时/失败时,它会通知它的委托。 我只是引用你的这篇文章,因为它听起来像你正试图实现一些非常相似的东西,而这个DownloadWrapper类完美地为我工作。 这是iOS5的新function,介意你。

这金块帮助我! 我正在使用同步NSURL,直到我决定我需要SSL我的客户端和我的服务器之间的连接。 我采取了比较设备上的证书和服务器上的证书(请参阅上面的链接)的关键固定的方法,为了使其工作,我需要添加代码到NSURL方法,从我的研究你无法与NSURL同步。 直到我发现这个简单的解决scheme为我工作:

 NSString *connectionRunLoopMode = @"connectionRunLoopMode"; NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:urlRequest delegate:urlConnectionDelegate startImmediately:NO]; NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop]; [connection unscheduleFromRunLoop:currentRunLoop forMode:NSDefaultRunLoopMode]; [connection scheduleInRunLoop:currentRunLoop forMode:connectionRunLoopMode]; [connection start]; while ([currentRunLoop runMode:connectionRunLoopMode beforeDate:[NSDate distantFuture]]); 

NSURLConnection已经是asynchronous的。 只需实现委托方法。 如果你想更新MainThread(例如进度条)上的UI,你可以在didReceiveData.这样做didReceiveData. 或者看看这个