2016-05-13 21 views
1

私はこの問題が約3〜4週間あります。私はグーグルでは、すべてをチェックしたが、まだ動作していない。私を助けてください!スクロール中のスクロール中にUITableViewフリーズ

スクロールするたびにcellForRowAtIndexPathtableViewをリロードしてフリーズします。

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{ 

    let cell = tableView.dequeueReusableCellWithIdentifier("cell")! as! MoviesTVC 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),{ 
     let dictionary = self.rows[indexPath.row] as? [String: AnyObject] 
     dispatch_async(dispatch_get_main_queue(),{ 
      cell.setCell(dictionary!) 
     }) 

    }) 

    return cell 
} 

setCell()機能:

func setCell(dictionary: AnyObject){ 
    let ImgString = dictionary["src"] as? String; 
    let ImgUrl = NSURL(string: ImgString!); 
    let ImgData = NSData(contentsOfURL: ImgUrl!) 
    self.movImg.image = UIImage(data: ImgData!); 
    self.movName.text = dictionary["name"] as? String; 
    self.movComment.text = dictionary["caption"] as? String; 
} 
+0

以下のPutz1103の観察に加えて、セルを非同期に更新するこのプロセスは、コード(または彼)が意図しているよりも複雑です。あなたは、(a)非同期要求が完了するまでにセルを再利用すること、 (b)ビューからスクロールされたセルに対する保留中の要求の後に、可視セル画像要求がバックログされる高速スクロール;参照してください。これをすべてうまくやっていることは自明ではなく、非同期イメージ検索をより適切に処理するUIImage拡張を検討することもできます。 http://stackoverflow.com/a/33505649/1271826を参照してください。 – Rob

+0

おそらく、非同期呼び出し後にセルが指定されたインデックスパスに対応しているかどうかをチェックする必要があります(オフスクリーンでスクロールされている可能性があります)。また、!オペレータ、多分あなたは "もしlet"を使用する必要があります –

答えて

2

あなたがバックグラウンド非同期タスク内のコードの間違ったビットを有するcellForRowAtIndexPath機能について

私のテーブルビューは、このようなものです。現在のところ、バックグラウンドで配列から値を取得するだけです。非常に高速なプロセスです...

難しいタスクをバックグラウンドで実行し、UIをフォアグラウンドで更新します。

let cell = tableView.dequeueReusableCellWithIdentifier("cell")! as! MoviesTVC 
let dictionary = self.rows[indexPath.row] as? [String: AnyObject] 
cell.setCell(dictionary!) 

return cell 


func setCell(dictionary: AnyObject){ 
    let ImgString = dictionary["src"] as? String; 
    let ImgUrl = NSURL(string: ImgString!); 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),{ 
     let ImgData = NSData(contentsOfURL: ImgUrl!) 
     let image = UIImage(data: ImgData!); 
     //Possibly resize the image here in the background task 
     //so that the cpu doesn't need to scale it in the UI thread 
     dispatch_async(dispatch_get_main_queue(),{ 
      self.movImg.image = image 
     }) 
    }) 
    self.movName.text = dictionary["name"] as? String; 
    self.movComment.text = dictionary["caption"] as? String; 
} 

編集:コメントであなたの質問に答えてください。最も簡単な解決策は、各セルの「画像」である属性を辞書に追加することです。次に、辞書の「イメージ」属性が存在する場合にセルをロードするときに、そのイメージをセルにロードするだけで済みます。存在しない場合はダウンロードして辞書に保存し、セルに追加します。

イメージをローカルリソースの場所にダウンロードするのが難しい解決方法です。次に、imageNamedを使用してファイルからイメージをロードします。これはあなたのためにキャッシュとメモリ解放を世話します。それがより良い選択肢になります。

さらにCoreDataを使用することもできます。これらのソリューションのいずれかで、実行中のファイルストレージを管理する必要があります。

+0

ありがとう!凍結問題は解決されましたが、この場合は移動するすべてのスクロールでイメージがダウンロードされます。つまり、スクロール中にsetCell()関数が呼び出されます。提案はありますか? –

+0

@CeyhunAshurbeyli私の編集を参照してください。 – Putz1103

+0

@CeyhunAshurbeyli - 一般的には、スクロールするときにイメージリクエストを開始する必要があります(たとえば、さらに3行表示するようにスクロールして、すぐにリクエストするようにします)。トリックは、画面からスクロールしたがまだ画像のダウンロードを完了していないセルの要求を停止したいということです。つまり、NSData(contentsOfURL:)を使用しないということです。 'UIImageView'の拡張機能がたくさんあり、優雅にこの要素を処理し、雑草からあなたを逃がします。 – Rob

関連する問題