由于滞后,TableViewController搜索结果无法正确加载

时间:2016-05-20 22:01:14

标签: ios swift uitableview

所以当我输入搜索时,我有一个可以提取电影结果的应用。 (与IMDb一样。)我使用themoviedb.org中的免费API加载结果。我在TableViewController中加载它们。我使用.dataTaskWithRequest方法上的mod加载结果的海报。使它同步。除此之外,它只是发送和接收电影或电视节目的标题,类型和年份的基本API。

现在我的应用程序因输入太快而滞后,因为同步加载,所以完全 ,因为当我根本不加载图片时它仍然会发生,但是图像加载也使应用程序滞后。现在这本身就是一个问题,但问题是,当应用程序将单词加载到屏幕上并完成滞后时,结果就是我在屏幕上显示的部分单词的结果。例如,如果我输入"辛普森一家"太快了,我得到" Sim"的结果,但如果我退格一次,并重新输入"辛普森一家",结果重新加载正确。更让事情变得更复杂的是,有时候我得到的最高结果只是旧的,部分结果之一,其余的都是正常的并且在下面加载。

Here is a video解释情况。我第一次打字"辛普森一家",你可以看到滞后。我输入的速度非常快,但它超过了""。当它完成加载时,它会加载一个甚至不应该存在的beowulf结果。我不知道发生了什么,它让我疯了。即使我没有加载图片,打字也不会滞后,结果仍然不会更新。

以下是相关的代码段,如果您需要,请随时询问。我不想立刻用太多代码轰炸你:

在搜索栏中输入文字时,会更新搜索结果:

libraryDependencies += "org.scala-lang" % "scala-compiler" % "2.11.8"

然后,在我得到结果后,我使用TableViewDataSource中的两个必需方法重新加载表:

extension SearchTable : UISearchResultsUpdating {
    func updateSearchResultsForSearchController(searchController: UISearchController) {

        //To Handle nils
        var searchBarText = searchController.searchBar.text
        if (searchBarText == nil) {
            searchBarText = ""
        }

        searchBarText! = searchBarText!.condenseWhitespace()

        //To Handle Disallowed Characters
        searchBarText = searchBarText!.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())

        //Find Results from themoviedb
        let urlString = "https://api.themoviedb.org/3/search/multi?query=" + searchBarText! + "&api_key= (I can't post the api key publicly online, sorry)"


        let results = NSURL(string: urlString)
        if (results == nil) {
            //Server Error
        }


        //Wire Up Results with matchingItems Array
        let task = NSURLSession.sharedSession().dataTaskWithURL(results!) { (data, response, error) -> Void in
            if let jsonData = data {

                do {
                    let jsonData = try NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers)


                    if var results = jsonData["results"] as? [NSDictionary] {
                        if results.count > 0 {
                           //Clean out non-english results:
                           //I wrote the function, it shouldn't be the source of the lag, but I can still provide it.
                            self.cleanArray(&results) 
                            self.matchingItems = results
                        } else {
                            self.matchingItems = []
                        }
                    }
                } catch {
                    //JSON Serialization Error
                }

            }
        }
        task.resume()
        self.tableView.reloadData()

    }
}

谢谢!

2 个答案:

答案 0 :(得分:0)

首先,我强烈建议您不要使用同步请求,主要是因为它会阻止您的用户界面直到完成,这对应用来说是一个非常糟糕的响应。

在您的情况下,您可以为UIImage放置一个占位符,并在请求完成后将其替换为正确的图像。

关于您更快打字的问题,它被称为 throttle debounce ,Apple建议:

  

性能问题。如果可以非常快速地执行搜索操作,则可以通过在委托对象上实现searchBar:textDidChange:方法来在用户键入时更新搜索结果。但是,如果搜索操作需要更多时间,您应该等到用户点击搜索按钮,然后再在searchBarSearchButtonClicked:方法中开始搜索。始终执行后台线程的搜索操作以避免阻塞主线程。这可以使您的应用在搜索运行时对用户做出响应,并提供更好的用户体验。

但如果你想让它自己处理,你可以看到这两个很好的答案,解释如何正确处理它:

我建议您按照Apple推荐的方式处理它,或者您可以改变自己的理念并采用一些自动处理它的库:

第一个更容易学习,第二个需要学习反应式编程和功能编程的概念,这取决于你。

我希望这对你有所帮助。

答案 1 :(得分:0)

对于那些可能在未来遇到同样问题而苦苦挣扎的人。首先,请阅读我对Victor Sigler的回答。

以下是问题:

1 - 我使用.dataTaskWithURL()在线搜索结果这是一个异步方法,在代码继续时在后台运行。因此,有时会在新结果出现之前重新加载表格。有关详细信息,请参阅this thread。如果您认真学习Swift,我高度建议您查看本教程的并发性:

www.raywenderlich.com/79149/grand-central-dispatch-tutorial-swift-part-1

2 - 由于搜索是同步的,图像滞后,正如Victor所说。他的回答几乎可以处理其余部分,所以请阅读它!