簡體   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