AFNetworking + NsOperationQueue - Pobierz tysiące obrazów
Pracuję nad zadaniem (tylko iOS5 +), które wymaga pobrania tysięcy obrazów z serwera. Obrazy należą do pewnych kategorii, a każda kategoria może mieć setki zdjęć. Muszę to zrobić: -
1) Upewnij się, że aplikacja pobiera brakujące obrazy w tle, jeśli aplikacja jest aktywna (nawet gdy użytkownik przegląda inne obszary aplikacji, które nie są związane ze zdjęciami).
2) Gdy użytkownik kliknie kategorię zdjęć, obrazy w tej kategorii muszą zostać pobrane jako priorytet, ponieważ są to te, które muszą być natychmiast widoczne.
Wszystko to dzieje się tylko wtedy, gdy obraz nie jest już dostępny w trybie offline. Po pobraniu obraz zostanie użyty z lokalnej pamięci masowej.
Aby rozwiązać ten problem, używam logiki: -
1) W AppDelegate.m, wapplicationDidBecomeActive
, Zaczynam zrzucać brakujące obrazy. Aby to zrobić, wykonuję zapytanie Core Data, sprawdzam, których obrazów brakuje, i zaczynam je pobierać w wątku z priorytetem BACKGROUND. Coś takiego :-
dispatch_queue_t imageDownloadQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_async(imageDownloadQueue, ^{
[DataDownloader downloadMissingImages];
});
dispatch_release(imageDownloadQueue);
ThedownloadMissingImages
kod wygląda tak: -
NSOperationQueue *downloadQueue = [[NSOperationQueue alloc] init];
downloadQueue.maxConcurrentOperationCount = 20;
for(MyImage *img in matches)
{
NSURLRequest *request = [NSURLRequest requestWithURL:img.photoUrl];
AFImageRequestOperation *operation = [AFImageRequestOperation imageRequestOperationWithRequest:request success:^(UIImage *image) {
[MyImage imageFromAPI:image inManagedObjectContext:document.managedObjectContext];
NSLog(@"Successfully downloaded image for %@", img.title);
}];
[downloadQueue addOperation:operation];
}
Działa to, ale blokuje główny interfejs użytkownika, a aplikacja po chwili ulega awarii. Wtedy próbuję pobrać około 700 obrazów. Z większą ilością zdjęć z pewnością się załamał.
2) Gdy użytkownik kliknie kategorię, muszę najpierw pobrać te obrazy, ponieważ muszą one zostać natychmiast pokazane użytkownikowi. Nie jestem pewien, jak mogę przerwać połączenie missingImages i powiedzieć, aby rozpocząć pobieranie niektórych obrazów przed innymi.
W zasadzie muszę pobrać wszystkie brakujące obrazy w tle, ale jeśli użytkownik przegląda kategorię zdjęć, obrazy te muszą mieć wysoki priorytet w kolejce pobierania.
Nie rozumiem, jak sprawnie działać. jakieś pomysły?
Dzienniki awarii wyglądają tak
PAPP(36373,0xb065f000) malloc: *** mmap(size=16777216) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
PAPP(36373,0xb065f000) malloc: *** mmap(size=16777216) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
Jun 24 11:39:45 MacBook-Pro.local PAPP[36373] <Error>: ImageIO: JPEG Insufficient memory (case 4)
Z góry dziękuję.