0

我看到有时加载 URL 失败的情况,但它失败得非常“严重”。当主机无法访问(即 VPN 未连接)时,似乎+[NSURLConnection(NSURLConnectionReallyInternal) _resourceLoadLoop:]经常挂起以下回溯:

(gdb) bt
#0  in mach_msg_trap ()
#1  in mach_msg ()
#2  in __CFRunLoopServiceMachPort ()
#3  in __CFRunLoopRun ()
#4  in CFRunLoopRunSpecific ()
#5  in +[NSURLConnection(NSURLConnectionReallyInternal) _resourceLoadLoop:] ()
#6  in -[NSThread main] ()
#7  in __NSThread__main__ ()
#8  in _pthread_start ()
#9  in thread_start ()

我已经实现- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error了,但它永远不会被调用。

我正在构建 NSURLRequest 如下:

NSURLRequest *theRequest = 
    [NSURLRequest requestWithURL:[NSURL URLWithString:url]
                     cachePolicy:NSURLRequestReloadIgnoringCacheData
                 timeoutInterval:5.0];

所以我假设请求应该在 5 秒后超时,而不是无限期地挂起。这没有发生。

我应该注意到这发生在 Mac OS X 的控制台应用程序中(它是 iOS 库的测试框架)。我想知道运行循环配置是否发生了“奇怪”的事情。(从跟踪来看,它可能正试图从它正在运行的运行循环中启动一个新的运行循环?!)

有任何想法吗?

编辑:由于这不是 Cocoa 应用程序,我不得不手动运行运行循环。这似乎是问题的一部分。

4

2 回答 2

1

我同意您提供的超时似乎应该启动。可能存在错误。

您可以通过在尝试连接之前检查网络可达性来稍微改善这个问题。请参阅SCNetworkReachability API

您还可以通过在运行循环上安装一个计时器来强制设置您自己的超时 - 您在您控制的线程上运行的计时器,而不是框架在后台运行的计时器 - 并在它触发时取消连接。

于 2012-05-10T02:03:50.870 回答
0

我解决了这个问题。出现问题是因为我没有给运行循环足够的时间。我有一些类似的代码:

[[NSRunLoop currentRunLoop] runUntilDate:
    [NSDate dateWithTimeIntervalSinceNow:5];

这只会导致运行循环运行 5 秒,这足以让我没有收到来自 URLConnection 的回调,说它失败了。我把它改成更像这样的东西,它起作用了:

[[NSRunLoop currentRunLoop] runUntilDate:
    [NSDate dateWithTimeIntervalSinceNow:10];

我认为在回溯中看到的副作用是 URLConnection 对象在尝试进行回调时无法检测到运行循环已停止,并且mach_msg_trap它可能正在等待回复,它永远不会收到。我无法完全解释这种行为,但这是一般理论。;-)

于 2012-05-10T06:07:35.313 回答