【问题标题】:Async networking + threading problem异步网络+线程问题
【发布时间】:2010-06-05 16:59:31
【问题描述】:

我启动了一个网络请求,假设与目标服务器通信不需要登录凭据。如果需要它们,那么我会收到一个身份验证质询,此时我会显示一个视图,请求用户提供所述凭据。提供它们后,我使用这些凭据重新启动网络请求。

只要我一次只做一个请求,这一切都很好。但我不是,通常情况下。

当两个请求都启动时,我得到第一个挑战,并呈现提示(使用 -presentModalViewController:)。然后是第二个挑战。当它尝试显示第二个提示时我崩溃了。

我将大部分内容封装在 @synchronized() 块中,但这没有任何效果,因为这些委托方法都在同一个(主)线程上调用。文档说委托方法是在启动连接的同一线程上调用的。好的,没问题;我将使用 -performSelectorInBackground 编写一个在后台线程上运行的方法:

NSURLConnection *connection = [[NSURLConnection alloc] 
                               initWithRequest:request 
                                      delegate:self
                              startImmediately:NO];
[connections addObject:connection];
[self performSelectorInBackground:@selector(startConnection:) 
                       withObject:connection];
[connection release];

- (void)startConnection:(NSURLConnection *)connection {
   NSAutoreleasePool *pool = [NSAutoreleasePool new];
   [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] 
                         forMode:NSDefaultRunLoopMode];
   [connection start];
   [pool drain];
}

它应该将每个网络请求及其回调放在自己的线程上,然后我的 @synchronized() 块将生效。

-initWithRequest 的文档:... state "发送给委托的消息将在调用此方法的线程上发送。默认情况下,要使连接正常工作,调用线程的运行循环必须在默认运行中运行循环模式。”好的,我正在这样做。

他们还声明“如果您通过 NO [for startImmediately],则必须在启动之前将连接安排在运行循环中。”好的,我也在做。

此外,NSRunLoop 的文档状态“每个 NSThread 对象,包括应用程序的主线程,都有一个根据需要自动为其创建的 NSRunLoop 对象。如果您需要访问当前线程的运行循环,您可以使用类方法当前运行循环。”我假设这适用于调用 -performSelectorInBackground... 创建的后台线程...(当我在 -startConnection: 方法中执行 'po [NSClassFromString(@"NSRunLoop") currentRunLoop]' 时似乎确实如此)。

-startConnection: 方法确实被调用了。但是在启动连接后,我现在再也没有收到 any 回调了。没有 -connectionDid… 委托方法。 (我什至尝试显式地启动线程的运行循环,但这并没有什么区别;我以前使用过这样的线程,而且我以前从来没有手动启动过运行循环——但我现在抓住了稻草。 ..)

我想我想出了一种解决方法,一次只处理一个请求,但它很笨拙,我想以正确的方式做到这一点。但是,我在这里错过了什么?

谢谢! 兰迪

【问题讨论】:

    标签: cocoa networking multithreading


    【解决方案1】:

    到达[pool drain]; 行了吗?我猜是这样。在此之后 -startConnection 方法退出,此时后台线程完成并销毁。这可能不是你想要的……

    您必须运行运行循环。你说你做了这个,它没有任何区别。这意味着你做错了。阅读Runloop section in the Threaded Programming Guide(最好是去适当的文档而不是听我说)。请注意,诸如 -performSelectorInBackground 之类的有用方法可能会使多线程看起来很有吸引力,但这很困难。

    还有,什么意思

    '包裹在@synchronized() 块中, 但这没有效果,因为这些 委托方法都被调用 在同一个(主)线程上'

    @synchronized() 在主线程上的作用与在后台线程上的作用相同。你认为它会做什么?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-01
      • 2020-01-03
      相关资源
      最近更新 更多