2017-07-26 24 views
5

私は簡単に解決できると思っていた非常に一般的な状況 - APIからフェッチされた各セルに画像を持つUICollectionViewを持つアプリケーションhttp/httpsを経由してWebサーバーに接続します。UICollectionViewとUITableViewで画像を最適にプリロード/プリフェッチする

私はiOS 10のprefetching in UICollectionViewを実装しようとしています。そのため、必要と思われる画像が事前に要求されています。

最適なプリフェッチのために満たされるべき様々な要件があるように私には思える

:イメージが既にある場合でも、実際には、すぐにいつもの投機的プリフェッチの上に優先すべきで必要とされている画像の

  1. フェッチは、フェッチされるキュー
  2. 特定のイメージをプリフェッチする必要がなくなったとiOSから通知された場合、プリフェッチキューからそのイメージを削除する必要があります。
  3. イメージが要求されている場合は、そのイメージの/ all/requestsがキャンセルされない限り、イメージは常に配信されます(1つのイメージが複数のセルまたは複数のビューコントローラで使用されていると、
  4. didEndDisplayingが呼び出された場合、優先度のあるフェッチを中止する必要があります(ただし、プリフェッチが要求され、取り消されなかった場合、イメージは優先度の低いキューに残っているはずです)。
  5. 単純に画像の読み込みに関連するさまざまな共通の要件です。基礎となるシステムにプリフェッチ要求をあふれさせないでください。プリフェッチ要求によって、すぐに必要なイメージから帯域幅とサーバースロットが離れてしまいます。

私はSDWebImageKingfisherのような様々な既存のライブラリを見て、どちらかのライブラリで簡単に上記の要件を満たすためにどのような方法があるように表示されていないことに驚いたしました。

たとえば、cancel all prefetchingしかないSDWebImageは2番目の要件を満たしていないか、画像ごとにプリフェッチャを作成する必要があります(プリフェッチャの同時リクエスト数を制限するなど、さまざまなSDWebImage機能を使用する必要があります)つまり、要件5は機能しなくなりました。)

これは本当に難しい問題ですか?私はいくつかの明白な解決策を見逃しましたか私は要件を熟考していますか?

答えて

0

最新のインデックスパスがから渡された場合は、prefetchItemsAt indexPathで十分ではありません。

要件1、2、3および優先度キュー(ソート済みヒープ)を使用して達成する必要があります。要件4は、優先度キューの実装によって異なります。 5は非常に広く、あいまいです。フェッチするメソッドの呼び出し回数を制限するだけです。プライオリティキューはジェネリックタイプを取ります。フェッチするアイテムのプロパティを持つオブジェクト/クラスで使用できるように、以下では単純化のためにIndexPath.rowを使用します。

データソースとキャッシュの間のメディエータとして機能する優先度キューを作成します。

次に、優先度キューをピック/デキューしてKingfisherに格納することによって、DataSourceからフェッチするようにデータを設定します。 あなたのデータソース - >優先度つきキュー - >キングフィッシャー - >セル

func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) { 
    ... 
    for indexPath in IndexPaths { 
     //Add the indexPath to the top of the priority queue 
     //highest priority is determined by the sort function you used when initializing the priority queue. 
     priorityQueue?.enqueue(indexpath.row) 
    } 

    //Call your method for getting the properties 
    self.fetchObjectsByPriority() 
} 


func fetchObjectsByPriority() { 
     if let count = priorityQueue?.count { 
     for _ in 0...count { 

      //get the index 
      var index = self.priorityQueue?.dequeue() 
      //Alternatively .peek() with out dequeuing item 
      //get image data and store 
      dataSource[index].image = ... 

     } 
    } 
} 

あなたはソート機能をプライオリティキューを初期化することを確認してください。

優先ビルドをhereから得ることができます。優先キューを作成するにはheapも必要です。問題のコードなしpriority Queuesheap sorting

より効果的なソリューションを提供することは困難です。私はこれが助け、歓声と幸運を望む!

関連する問題