2016-02-11 17 views
5

Przechowuję około 100 UIImage w jednej tablicy. Wiem, że istnieje problem z używaniem pamięci, który ostatecznie powoduje awarię aplikacji, w szczególności na starszych urządzeniach (iPhone 4s). Pod względem User Experience przechowywanie wszystkich UIImages na DocumentsDirectory - nie jest opcją (trwa zbyt długo). Więc myślałem o "połączeniu" tych dwóch metod. Zaczekaj, aż otrzymam ostrzeżenie o użyciu pamięci, zatrzymam zapisywanie obrazów w mojej macierzy, a następnie zacznę zapisywać na dysku. Nie mogę znaleźć właściwą drogę do obsługi Memory leak/warning/usage callProblem z pamięcią podczas pracy z dużą tablicą UIImage

override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     print("memory warning") 
    } 

gdy jestem badania na rzeczywistym urządzeniu, to jest po prostu wywala - bez wywołania metody. Jakieś sugestie?

+1

myślę, jeśli masz problemy takie jak to, czy Zmniejsz jakość zdjęć lub spraw, aby poczekać, aż aplikacja zapisze na dysku. – brimstone

+0

Hej @GabrielJones. Niestety nie mogę. Ze względu na potrzeby mojej aplikacji wszystkie powinny istnieć razem. Nie mogę oddzielić grupy innymi słowami. –

+0

@GabrielJones, a właściwie zmniejszyłem jakość o prawie 60% (co jest nawet mniejsze niż to, czego potrzebuję). Dobrym pytaniem może być, jaki jest najskuteczniejszy sposób na zmianę rozmiaru obrazu pod względem jakości/bajtów. –

Odpowiedz

1

Spróbuj użyć biblioteki pamięci podręcznej obrazu. Porównanie najpopularniejsza jest tutaj: https://bpoplauschi.wordpress.com/2014/03/21/ios-image-caching-sdwebimage-vs-fastimage/

doświadczenie: SDWebImage jest najlepszy dla obrazów URL-pochodzą zazwyczaj z Internetu i Haneke jest dobre dla obrazów tożsamości opartej na przykład miniaturki generowane z filmem. Obie dostępne w CocoaPods.

Program SDWebImage korzysta z bazy danych SQL bazy danych CoreData do buforowania adresów URL. Nie ma metod "ręcznego" tworzenia obrazów, ale na całym świecie popularne w ~ aplikacjach REST pobierających obrazy z Internetu. Używam go w właśnie opublikowanej aplikacji AppStore MyHairDressers. FastCache używa plików do buforowania adresów URL. Ale podobnie jak SDWebImage nie nadaje się do przechowywania obrazów "ręcznie robionych" w pamięci podręcznej. Oba doskonale nadają się do zdjęć pobranych przez adresy URL. Haneke może przechowywać obrazy według niestandardowych identyfikatorów nie tylko przez adresy URL. Ale podobnie jak w przypadku FastCache, wymaga to pewnej konfiguracji. Oto kod dla niektórych konfiguracjach:

`

HNKCacheFormat *cacheFormatThumbnail = [[HNKCache sharedCache] formats][CACHE_FORMAT_THUMBNAIL]; 
     if (cacheFormatThumbnail == nil) 
     { 
      cacheFormatThumbnail = [[HNKCacheFormat alloc] initWithName:CACHE_FORMAT_THUMBNAIL]; 
      cacheFormatThumbnail.size = CGSizeMake(100.0f, 56.0f); 
      cacheFormatThumbnail.scaleMode = HNKScaleModeAspectFit; 
      cacheFormatThumbnail.compressionQuality = 0.5f; 
      cacheFormatThumbnail.diskCapacity = 10 * 1024 * 1024; // 10MB 
      cacheFormatThumbnail.preloadPolicy = HNKPreloadPolicyLastSession; 
      [[HNKCache sharedCache] registerFormat:cacheFormatThumbnail]; 
     } 
     HNKCacheFormat *cacheFormatPhoto = [[HNKCache sharedCache] formats][CACHE_FORMAT_PHOTO]; 
     if (cacheFormatPhoto == nil) 
     { 
      cacheFormatPhoto = [[HNKCacheFormat alloc] initWithName:CACHE_FORMAT_PHOTO]; 
      CGFloat scale = [[UIScreen mainScreen] scale]; 
      cacheFormatPhoto.size = CGSizeMake(1280.0f * scale, 720.0f * scale); 
      cacheFormatPhoto.scaleMode = HNKScaleModeAspectFit; 
      cacheFormatPhoto.compressionQuality = 0.5f; 
      cacheFormatPhoto.diskCapacity = 50 * 1024 * 1024; // 50MB 
      cacheFormatPhoto.preloadPolicy = HNKPreloadPolicyNone; 
      [[HNKCache sharedCache] registerFormat:cacheFormatPhoto]; 
     } 

`

i tutaj jest przykład do tworzenia pamięci podręcznej obrazów (TableViewCell zawiera CollectionView z miniaturkami):

`

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    VideoCell *cell = (VideoCell *)[super tableView:tableView cellForRowAtIndexPath:indexPath]; 
    VideoAsset *asset = (VideoAsset *)[self.fetchedResultsController objectAtIndexPath:indexPath]; 
    if ([asset thumbnails] == 0) 
    { 
     MBProgressHUD *hud = [[MBProgressHUD alloc] initWithView:[cell thumbnails]]; 
     hud.removeFromSuperViewOnHide = YES; 
     [[cell thumbnails] addSubview:hud]; 
     hud.labelText = NSLocalizedString(@"H11",nil); 
     [hud show:YES]; 
     CGFloat scale = [[UIScreen mainScreen] scale]; 
     CGSize size = CGSizeMake(100.0f * scale, 56.0f *scale); 
     __weak typeof(cell) weakCell = cell; 
     [asset generateThumbnails:self->thumbnailsCount offset:self->thumbnailsOffset size:size completion:^(NSArray *thumbnails) { 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       [hud hide:YES]; 
      }); 
      if ((thumbnails != nil) && ([thumbnails count] > 0)) 
      { 
       HNKCache *cache = [HNKCache sharedCache]; 
       NSUInteger n = 0; 
       NSUInteger keyHash = [[[asset assetURL] absoluteString] hash]; 
       for (UIImage *image in thumbnails) 
       { 
        [cache setImage:image forKey:[NSString stringWithFormat:@"%[email protected]%i",(unsigned long)keyHash,(int)(n++)] formatName:CACHE_FORMAT_THUMBNAIL]; 
        dispatch_async(dispatch_get_main_queue(), ^{ 
         if (weakCell != nil) 
         { 
          __strong typeof(cell) strongCell = weakCell; 
          [[strongCell thumbnails] reloadData]; 
         } 
        }); 
formatName:CACHE_FORMAT_PHOTO]; 
       } 
      } 
     }]; 
    } 
    return (UITableViewCell *)cell; 
} 

``

i stosując (kolekcja widok komórkę kolekcji w komórce widoku tabeli):

`

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 
{ 
    ThumbnailCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath]; 
    NSString *key = [NSString stringWithFormat:@"%[email protected]%i",(unsigned long)[[[(VideoAsset *)self->_selectedObject assetURL] absoluteString] hash],(int)[indexPath item]]; 
    [cell setKey:key]; 
    [cell setTag:[indexPath item]]; 
    __weak typeof(cell) weakCell = cell; 
    [[HNKCache sharedCache] fetchImageForKey:key formatName:CACHE_FORMAT_THUMBNAIL success:^(UIImage *image) { 
     [[weakCell image] setImage:image]; 
    } failure:^(NSError *error) { 
     if ([[error domain] isEqualToString:HNKErrorDomain] && ([error code] == HNKErrorImageNotFound)) 
     { 
      [[weakCell image] setImage:[UIImage imageNamed:@"movieplaceholder"]]; 
     } 
     else [error reportError]; 
    }]; 
    return cell; 
} 

`

+0

Dzięki, sprawdzę! –

+0

Program SDWebImage korzysta z bazy danych SQL bazy danych CoreData do buforowania adresów URL. Nie ma metod "ręcznego" tworzenia obrazów, ale na całym świecie popularne w ~ aplikacjach REST pobierających obrazy z Internetu. Używam go w właśnie opublikowanej aplikacji AppStore MyHairDressers. –

+0

Wiem, że jest to bardzo przydatne przy pobieraniu online, ale używam lokalnych utworzonych obrazów. I potrzebuję zachować je jak ponad pamięcią podręczną, co najmniej wypełnić pamięć podręczną i tylko je przechowywać –