所以当我输入搜索时,我有一个可以提取电影结果的应用。 (与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()
}
}
谢谢!
答案 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所说。他的回答几乎可以处理其余部分,所以请阅读它!