私は、ユーザータイプとしてウェブから動画検索結果を読み込むアプリケーションを持っています。私は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 }
はい、これは解決策ではありません。 :/私はまた、セルのid#が同じであるかどうかを調べることができますが、indexPathがもう存在しない場合など、これもクラッシュする可能性があります。私は自分のコードを書き直す方法が欲しい。私はこれが難しいことを知っている、私はこれについて多く考えた。私は解決策を見つけることができません。 – QuantumHoneybees
これは標準のUITableViewCellビヘイビアです。どのラインでクラッシュするのですか? 'indexPath'はゼロにならないことが保証されています。 'tableView.indexPathForCell(cell)'はnilでもかまいませんが、tableView.indexPathForCell(cell)== indexPath'がfalseに評価された場合にだけ、その原因となります。 – beyowulf
これは、私が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