我正在使用正在进行异步网络调用的代理。响应将被处理并作为参数传递给下一行中的方法。代码说明如下:
- (MyClass *) performOperations{
...
...
[self callProxyMethodsTarget:self action:@selector(receivedValue:) withObject:anObject]; //making an asynchronous call here
return response;
}
- (void) receivedValue:(id)response{ ///need this return value from network call to return from performOperartions
...
...
}
我的问题是,由于代理方法正在进行异步网络调用,我无法及时获得响应以返回它。
我想过很多事情,比如:
我想到了一个像以下的解决方案:
- (MyClass *) performOperations{
...
...
[self callProxyMethodsTarget:self action:@selector(receivedValue:) withObject:anObject]; //making an asynchronous call here
///write a code here to wait until response is received
return response;
}
- (void) receivedValue:(id)response{ ///need this return value from network call to return from performOperartions
...
...
}
但未能这样做。
答案 0 :(得分:2)
我假设没有从主线程调用performOperations
,因为如果是,那么你就麻烦了。否则,您可以像这样使用当前的运行循环:
- (MyClass *) performOperations{
_isValueReceived = NO;
...
...
[self callProxyMethodsTarget:self action:@selector(receivedValue:) withObject:anObject]; //making an asynchronous call here
// Start with 10ms time boxes
NSTimeInterval ti = 0.01;
// Wait until delegate did callback
while (!_isValueReceived) {
NSDate* date = [NSDate dateWithTimeIntervalSinceNow:ti];
// Let the current run-loop do it's magif for one time-box.
[[NSRunLoop currentRunLoop] runMode:NSRunLoopCommonModes
beforeDate:date];
// Double the time box, for next try, max out at 1000ms.
ti = MIN(1.0, ti * 2);
}
return response;
}
- (void) receivedValue:(id)response {
...
...
_isValueReceived = YES;
}
这就像你的后台线程的魅力一样,而且正是GNUStep如何使用异步I / O实现分布式对象的同步方法调度,所以应该非常接近Cocoa在内部的方式。
然而,在主线程上执行不安全,因为UIKit在默认模式下重新进入运行循环是不安全的。
答案 1 :(得分:1)
您需要稍微重构一下您的应用程序。您不能等到结果到达的位置,因为这将阻止主线程,这意味着运行循环上的事件将不会被服务。这有两个原因
您需要为应用程序创建一些状态,例如标记proxyRequestMade
并在您发出请求时设置它。然后该方法将返回到运行循环而不返回值。
然后,当您收到响应时,您需要处理它并重置标志。您拥有该标志的原因是它可能会改变您处理其他UI事件的方式,例如您可以在发出请求时禁用某些按钮。
答案 2 :(得分:0)
代理方法是否具有表明其操作已完成的委托协议?
如果是这样 - 我不知道你的情况,但如果你控制了代码,那么你可以添加它们 - 然后你可以将调用对象设置为代理方法的委托,调用代理调用方法结束时的方法,并在调用委托方法时恢复。
编辑示例代码
您的方法无法像现在这样工作,因为第一个方法 - 调用代理方法的方法 - 无法返回值。它可能需要有一个委托协议,无论是什么调用它。
- (void) performOperations {
...
if (proxyMethod == nil) {
ProxyMethod *proxyMethod = [[ProxyMethod alloc] init];
}
[proxyMethod callProxyMethodsTarget:self action:@selector(receivedValue:) withObject:anObject]; //making an asynchronous call here
}
//Assuming this the the delegate method from the proxy object
- (void) receivedValue:(id)response {
// Continue with calling thread here
// Return information to whatever called performOperations via
// a delegate method or a notification
}