2016-05-24 2 views
0

私は、ユーザータイプとしてウェブから動画検索結果を読み込むアプリケーションを持っています。私は0.3秒ごとに一度だけリロードするように検索リクエストを絞ります。 (これはおそらくまったく関連していませんが、何が問題なのでしょうか?)今私の問題はこれです。Swift - 検索結果を読み込む際の同時性の問題。画像をロードしてリクエストを送信しますが、リクエストが遅すぎます

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 
    } 
    

答えて

0

、私は、あなたが非同期要求をキャンセルすることを可能にするネットワークライブラリをAlamofireを使用。 Objective-Cを使用している場合は、AFNetworkingを参照してください。 Objective-Cでも同じことです。

1

セルの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 
          } 
         } 
        } 
       } 
      }) 
+0

はい、これは解決策ではありません。 :/私はまた、セルのid#が同じであるかどうかを調べることができますが、indexPathがもう存在しない場合など、これもクラッシュする可能性があります。私は自分のコードを書き直す方法が欲しい。私はこれが難しいことを知っている、私はこれについて多く考えた。私は解決策を見つけることができません。 – QuantumHoneybees

+0

これは標準のUITableViewCellビヘイビアです。どのラインでクラッシュするのですか? 'indexPath'はゼロにならないことが保証されています。 'tableView.indexPathForCell(cell)'はnilでもかまいませんが、tableView.indexPathForCell(cell)== indexPath'がfalseに評価された場合にだけ、その原因となります。 – beyowulf

+0

これは、私がindexPathが何であるか誤解したことに起因すると思います。私は[NSIndexPath](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSIndexPath_Class/index.html#//apple_ref/occ/cl/NSIndexPath)のドキュメントを見てきました。 )しかし、私はまだ理解していません。これが同じセルにいるかどうかを確認している場合(#4としましょう)、search1のcell4の画像結果がsearch2のcell4に読み込まれるため、search2の画像結果を再読み込みします。何か不足していますか? – QuantumHoneybees

関連する問題