2017-07-26 51 views
5

Mam to, co mógłbym sobie wyobrazić, to bardzo częsta sytuacja, której oczekiwałem, że będzie łatwa do rozwiązania - aplikacja z UICollectionView, z obrazem w każdej komórce, która jest pobierana z interfejsu API na serwerze WWW przez http/https.Optymalne wstępne ładowanie/wstępne pobieranie obrazów w UICollectionView i UITableView

Próbuję zaimplementować iOS 10's prefetching in UICollectionView, aby obrazy, które prawdopodobnie będą wymagane, są wymagane z wyprzedzeniem.

Wydaje mi się, że istnieją różne wymagania, które powinny być spełnione w celu uzyskania optymalnej prefetching:

  1. pobierania obrazów, które są rzeczywiście natychmiast wymagane powinno być zawsze priorytetem powyżej spekulacyjnego prefetching, nawet wtedy, gdy obraz jest już w kolejka do pobrania.
  2. Gdy iOS mówi nam, że dany obraz nie jest już wymagany do wstępnego wyboru, to (i tylko to) powinien zostać usunięty z kolejki wstępnego pobierania.
  3. Jeśli obraz jest wymagany, powinien być zawsze dostarczony, chyba że/all/wnioski o to zostaną anulowane (łatwo się pomylić, jeśli jeden obraz jest używany w wielu komórkach lub wielu kontrolerach widoku).
  4. Priorytetowe pobieranie powinno zostać przerwane, jeśli wywołano wywołanie e-maila (ale jeśli żądanie wstępne było wymagane i nie zostało anulowane, obraz powinien pozostać w kolejce z niższym priorytetem).
  5. Różne typowe wymagania, które odnoszą się po prostu do ładowania obrazów - np. nie zalewaj bazowego systemu żądaniami preselekcji, które w ostatecznym rozrachunku usuwają przepustowość i gniazda serwerów z obrazów, które są wymagane natychmiast.

szukałem w różnych istniejących bibliotek takich jak SDWebImage i Kingfisher i był zaskoczony, że nie wydaje się być jakiś sposób, aby łatwo spełnić powyższe wymagania zarówno z biblioteki.

Na przykład SDWebImage nie spełnia drugiego wymogu - możesz tylko cancel all prefetching, lub musisz utworzyć pre-fetcher na obraz (co oznacza różne inne funkcje SDWebImage, takie jak ograniczenie liczby równoczesnych żądań pobrane obrazy - tj. wymaganie 5 - już nie działa.)

Czy to naprawdę trudny problem? Czy brakowało mi jakiegoś oczywistego rozwiązania? Czy zastanawiam się nad wymaganiami?

Odpowiedz

0

Wygląda na to, że konieczne jest zaimplementowanie własnego priorytetu, jeśli ostatnia ścieżka indeksu od prefetchItemsAt indexPaths nie jest wystarczająca.

Wymogi 1, 2, 3 i należy je zrealizować za pomocą kolejki priorytetowej (posortowane sterty). Wymaganie 4 zależy od realizacji kolejki priorytetowej. 5 jest dość szeroki i niewyraźny, wystarczy ograniczyć liczbę wywołań do twojej metody pobierania. Kolejka priorytetów przyjmuje typ ogólny, dzięki czemu można jej używać z obiektem/klasą, która ma właściwości dla elementów, które chcesz pobrać, poniżej używam tylko IndexPath.row dla uproszczenia.

Utwórz kolejkę priorytetową, która będzie służyć jako mediator między źródłem danych a pamięcią podręczną.

następnie ustaw dane do pobrania z DataSource, zaglądając/odkładając kolejkę priorytetową i przechowując je w Kingfisher. Twój DataSource -> kolejka priorytetowa -> Kingfisher -> Komórka

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 = ... 

     } 
    } 
} 

upewnij się zainicjować priorytet kolejki z funkcją sortowania.

Możesz uzyskać wstępnie zbudowaną kolejkę priorytetową od here, aby utworzyć kolejkę priorytetową, musisz również heap.

więcej na priority Queues i heap sorting

bez kodu w pytaniu trudno oferować skuteczne rozwiązanie. Mam nadzieję, że to pomoże, okrzyki i powodzenia!