繁体   English   中英

Swift-加载搜索结果时的并发问题。 我加载图像,发送请求,但是请求为时已晚

[英]Swift - Concurrency issue when loading search result. I load the images, send the requests, but the requests are too late

因此,我有一个应用程序可以根据用户类型从网络实时加载电影搜索结果。 我限制了搜索请求,以便每0.3秒仅重新加载一次。 (这可能根本不相关,但是到底是什么)。 现在我的问题是这个。

1-输入搜索词,例如“ Search1”。 为了节省时间,我立即(几乎)加载了每个结果的标题,年份和类型。 我保持张贴者为黑色,并发送异步请求以加载图像,因为这会花费更多时间。 我等待图像加载。

2-在加载图片之前,我先输入另一个术语,例如“ Search2”。 所以我得到了“ Search2”的文本结果,也许还有一些图像。

3-但是,随后开始出现对“ Search1”的旧请求,它们替换了Search2的请求,因为它们的加载速度较慢。 我得到的是新旧图像的组合,因为我无法取消旧请求。

我该如何解决? 如果用户再次开始输入,我需要一种方法来告诉设备停止加载旧图像,并且我无法取消异步请求。 我该如何解决?

码:

  • 细胞节流的东西

    func updateSearchResultsForSearchController(searchController:UISearchController){

     // to limit network activity, reload 0.3 of a second after last key press. NSObject.cancelPreviousPerformRequestsWithTarget(self, selector: "reload:", object: searchController) if (!UIApplication.sharedApplication().networkActivityIndicatorVisible) { UIApplication.sharedApplication().networkActivityIndicatorVisible = true self.tableView.reloadData() } self.performSelector("reload:", withObject: searchController, afterDelay: 0.3) } 
  • 这是加载每个单元格信息的代码:

      override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("cell")! as! CustomCell //Safe-Guard. This shouldn't be needed if I understood what I was doing if (indexPath.row < matchingItems.count) { cell.entry = matchingItems[indexPath.row] //404 /* . . omitted code that loads up text info (title, year, etc.) . . */ //Poster cell.poster.image = nil if let imagePath = matchingItems[indexPath.row]["poster_path"] as? String { //Sessions and Stuff for request let url = NSURL(string: "http://image.tmdb.org/t/p/w185" + imagePath) let urlRequest = NSURLRequest(URL: url!) let session = NSURLSession.sharedSession() //Asynchronous Code: let dataTask = session.dataTaskWithRequest(urlRequest, completionHandler: { (data, response, error) -> Void in if let poster = UIImage(data: data!) { //I want to stop this piece from running if the user starts typing again: dispatch_async(dispatch_get_main_queue()) { //Animate the poster in cell.poster.alpha = 0.0 // hide it cell.poster.image = poster // set it UIView.animateWithDuration(1.0) { cell.poster.alpha = 1.0 // fade it in } } } }) dataTask.resume() } else { //Just use placeholder if no image exists cell.poster.image = UIImage(named: "Placeholder.jpg") } } return cell } 

您可以只检查单元格的indexPath,看看它是否相同或是否已出队并重新用于另一行。

let dataTask = session.dataTaskWithRequest(urlRequest, completionHandler: { (data, response, error) -> Void in
                if let poster = UIImage(data: data!) {
                //I want to stop this piece from running if the user starts typing again:
                    dispatch_async(dispatch_get_main_queue()) {
                        //Animate the poster in
                        if tableView.indexPathForCell(cell) == indexPath {
                            cell.poster.alpha = 0.0     // hide it
                            cell.poster.image = poster  // set it
                            UIView.animateWithDuration(1.0) {
                                cell.poster.alpha = 1.0 // fade it in
                            }
                        }
                    }
                }
            })

对于将来遇到同样问题的人,我使用了Alamofire (网络库),该库允许您取消异步请求。 如果使用Objective-C,则查找AFNetworking。 这是相同的,但对于Objective-C。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM