异步调用中的异步调用未执行

时间:2016-08-31 15:28:44

标签: ios swift swift2 nsurlsession

我尝试从rss Feed中检索XML,获取每篇文章的链接,然后从这些文章中提取信息。我使用AEXML获取xml,使用ReadabilityKit进行链接提取。

我成功地从XML中提取链接,但是对Readability的解析器调用永远不会执行。我不希望这个主线程阻止所有UI,但到目前为止,这是我使其工作的唯一方式。代码如下(删除了调度获取主队列):

func retrieveXML() {
    let request = NSURLRequest(URL: NSURL(string: "<XML URL HERE>")!)
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
        (data, response, error) in

        if data == nil {
            print("\n\ndataTaskWithRequest error: \(error)")
            return
        }

        do {
            let xmlDoc = try AEXMLDocument(xmlData: data!)
            for child in xmlDoc.root.children {

                if let postURL = child["id"].value {

                    let url = NSURL(string: postURL)
                    let parser = Readability(url: url!)
                    let title = parser.title()
                    print("TITLE: \(title)")
                }
            }
        } catch {
            print(error)
        }
    }
    task.resume()
}

2 个答案:

答案 0 :(得分:1)

感谢报道。新版本可在可可豆荚和推车上使用新的aync API。 Sync API已从项目中删除。

field1:val1:extra1
val2:extra1
val3

感谢您的贡献!有关详细信息,请查看自述文件https://github.com/exyte/ReadabilityKit

答案 1 :(得分:0)

问题是Readability正在陷入僵局。您从NSURLSession完成块(默认为串行队列)调用它,但Readability阻塞该信号量队列,直到其自己的网络请求完成。所以Readability是死锁的,因为它阻塞了一个线程,等待一个信号量信号,该信号应该从它阻塞的同一个线程发送。

您可以通过异步将实例化Readability的代码分派到单独的队列(例如全局队列)来解决此问题。

dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)) {
    let url = NSURL(string: postURL)
    let parser = Readability(url: url!)
    let title = parser.title()
    print("TITLE: \(title)")
}

看起来API已经更新为异步运行,因此获取最新版本并消除了此死锁问题,并且不需要上述异步调度。您显然必须使用更新的API的完成处理程序模式。