等待代码执行完毕

7
我想知道在Objective-C项目中等待代码执行完成的最简单方法,因为我正在调用Web服务并检索结果,但它在WebService完成被调用和填充之前就已经检索到了结果。有什么建议吗?
顺便说一下,这是我的Web服务代码:
    NSMutableURLRequest *theRequest=[NSMutableURLRequest requestWithURL:tmpURl];

[theRequest addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];

[theRequest addValue:@"http://tempuri.org/GetCategory" forHTTPHeaderField:@"SOAPAction"];

NSString *msgLength=[NSString stringWithFormat:@"%i",[soapMessage length]];

[theRequest addValue:msgLength forHTTPHeaderField:@"Content-Length"];

[theRequest setHTTPMethod:@"POST"];

[theRequest setHTTPBody:[soapMessage dataUsingEncoding:NSUTF8StringEncoding]];

NSURLConnection *conn=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

我正在使用的代码从另一个类调用此方法:

images = [ws callWebService:api :data];

        images = [ws returnArray];

现在的问题是,第二行代码在第一行完成之前就被执行了。

你目前是如何使用代码调用该网络服务的? - BoltClock
我有一个用于Web服务的类,我使用SOAP。 - Lilz
2个回答

22

您可以轻松地按以下方式完成:

-(void)aFunc {

Do Asynchronous A job...

while (A is not finished) {
// If A job is finished, a flag should be set. and the flag can be a exit condition of this while loop

// This executes another run loop.
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];

}

Do things using the A's result.

}

我不明白如何使用这个。 - Lilz
以上代码在主线程中运行。 你可以把A jos看作是HTTP请求者(异步的...)。当你等待异步任务时,上述代码非常有用。更多详情请参见http://blog.sallarp.com/iphone-ipad-wait-for-asynchronous-nsrunloop-task-to-complete/。 - alones
你的意思是说,你会暂停流程、锁定用户界面等待结果吗?你是认真的吗?你知道代理、通知、KVO等技术吗? - vfn
另一个想法是......你所说的等待异步请求,是什么意思?如果您要一直等待才能继续,那么为什么它是异步的?据我所知,异步应该用于这样的情况:“你,做这个并在完成后让我知道,因为我不能等待你完成,停在这里一动不动。” - vfn
上面的回复是关于用户的问题。虽然强制将异步任务变成同步可能不是最好的方法(因为这就是委托的全部目的),但这是一个很好的回应。 - Filipe Pina

4
您可以使用许多Cocoa设计模式中的其中之一(委托、通知等)。
例如,您将触发方法并等待接收响应。
看起来您正在使用异步请求,在这种情况下,您需要等待其中一个委托方法被通知请求已完成(带有错误或成功)。
顺便问一句,您的请求是什么样子的?您能分享一些代码来解释您如何发出请求以及何时以及想要做什么吗?
在插入代码后进行编辑:
您将self设置为请求的委托,因此您应该能够处理响应。
请查看NSURLConnection类参考。当请求完成时,您需要在这些方法上触发您的解析器,例如:
 connection:didReceiveResponse:
 connection:didReceiveData:
 connection:didFailWithError:

干杯,

vfn


这对我不起作用,因为这些方法也是该类的一部分,并且它们是从主类调用的。 - Lilz
为什么这段代码可以适用于其他人,但是对你不起作用呢?这些方法会在请求完成时被调用。根据你的代码或应该将类设置为代理,在你调用方法的类中实现如下代码:[ws callWebService:api data:data delegate:self]; 然后在这个类中实现代理方法。 - vfn
我的问题是我有两个类:假设为A和B。现在我需要从A中调用以下代码: images = [b callWebService:api :data]; images = [b returnArray];其中b是B类的一个实例。 现在我在B类中有connection:didReceiveResponse方法,但在第一行代码之前,它会先执行第二行代码。 - Lilz
这是你代码的问题。a 应该是请求的代理,而不是 b。你不应该执行 images = [b returnArray]; 因为它没有意义,因为你依赖于请求完成才能获取数据。 - vfn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接