2

使用 initWithContentsOfURL 解析提要时如何设置超时。有时我们的提要返回一个空白响应,然后它会尝试永远解析提要。我想设置 30 秒左右的超时时间,这样会弹出一个 UIAlertView,然后尝试重新解析提要。

    NSURL *feedURL = [[NSURL alloc] initWithString:URL];
    NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:feedURL];
    [parser setDelegate:self];
    [parser setShouldProcessNamespaces:NO];
    [parser setShouldReportNamespacePrefixes:NO];
    [parser setShouldResolveExternalEntities:NO];

    [parser parse];
4

3 回答 3

3

第一种方法: 使用延迟选择器

可能最简单的方法是使用 NSObject 的performSelector:withObject:afterDelay:方法。您可以这样定义一些方法parsingDidTimeout

- (void)parsingDidTimeout {
    if(self.parsingDidComplete == NO) {
        [self.parser abortParsing];
        // Create your error and display it here

        // Try the fetch and parse again...
    }
}

这要求您将解析器作为实例变量 ( self.parser) 挂起,以便您可以从您定义的方法中取消它。它还要求您的解析器委托跟踪解析器是否已完成(self.parsingDidComplete可以在委托的方法中默认NO并设置为)。这是为了避免中止成功的解析。完成后,只需要一个简单的YESparserDidEndDocument:

[self performSelector:@selector(parsingDidTimeout) withObject:nil afterDelay:30];

三十秒后,你的解析中止代码将被调用,你可以做任何你需要做的事情。

第二种方法: 使用计时器

通过使用NSTimer而不是 NSObject 方法调用,您可以在 timeout 方法中使整个方法(可以说)更简单。这样,如果解析器成功完成,您可以简单地使计时器无效,从而允许您消除方法if中的子句parsingDidTimeout(因此,也摆脱了BOOLivar)。计时器初始化如下所示:

NSTimer *timer = [NSTimer timerWithTimeInterval:30.0
                                         target:self
                                       selector:@selector(parsingDidTimeout)
                                       userInfo:nil
                                        repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
于 2009-12-04T20:55:51.690 回答
1

NSURLConnection不回答您的问题方向,但如果您曾经下载数据,则可以完全控制请求和响应周期(以及没有额外线程的异步性) 。这就是initWithContentsOfURL:在幕后所做的。

于 2009-12-04T20:56:35.643 回答
0

NSTimer使用aka的 Swift 3 示例Timer

func startParseTimeoutTimer() {
    Timer.scheduledTimer(withTimeInterval: 2.0, repeats: false) { (_) in
        if (self.busy) {
            self.parser?.abortParsing()
            self.parser = nil
            print("Show UI as NOT busy; we aborted for timeout \(Thread.current.isMainThread)")
        }
    }

}
于 2017-03-20T15:33:31.960 回答