2015-09-07 3 views
3

J'utilise PhotoKit pour aller chercher des photos de l'album système et les mettre dans un UICollectionView.Comment réduire l'utilisation de la mémoire avec PhotoKit?

  1. Pour le UICollectionViewCell, je l'ai mis comme ceci:

    cell.imageView.contentMode = UIViewContentModeScaleAspectFill; 
    
  2. Quand paraphant mon UICollectionView, je vais chercher la photo PHAsset de collection: Camera Roll seulement:

    PHFetchResult *fetchResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil]; 
    [fetchResult enumerateObjectsUsingBlock:^(PHAssetCollection *collection, NSUInteger idx, BOOL *stop) { 
        NSLog(@"ALBUM NAME: %@", collection.localizedTitle); 
        if ([collection.localizedTitle isEqualToString:@"Camera Roll"]) { 
         _fetchedPhotos = [PHAsset fetchAssetsInAssetCollection:collection options:nil]; 
         _pickedStatuses = @[].mutableCopy;    
    
         NSMutableArray *assets = @[].mutableCopy; 
    
         _manager = [[PHCachingImageManager alloc] init]; 
         _options = [[PHImageRequestOptions alloc] init]; 
         _options.resizeMode = PHImageRequestOptionsResizeModeExact; 
         _options.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic; 
    
         CGFloat scale = [UIScreen mainScreen].scale; 
         CGSize targetSize = CGSizeMake(layout.itemSize.width*scale, layout.itemSize.height*scale); 
    
         //I'm not sure if this api should be called here 
         [_manager startCachingImagesForAssets:assets targetSize:targetSize contentMode:PHImageContentModeAspectFill options:_options]; 
        } 
    }]; 
    
  3. Ensuite, Je demande le UIImage de PHFetchResult d'en haut comme th est:

    -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 
    { 
        MYCell *cell = (MYCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"reuseCell" forIndexPath:indexPath]; 
    
        CGFloat scale = [UIScreen mainScreen].scale; 
        CGSize targetSize = CGSizeMake(_layout.itemSize.width*scale, _layout.itemSize.height*scale); 
    
        PHAsset *asset = _fetchedPhotos[indexPath.item]; 
        [_manager requestImageForAsset:asset targetSize:targetSize contentMode:PHImageContentModeAspectFill options:_options resultHandler:^(UIImage *result, NSDictionary *info) { 
         cell.imageView.image = result; 
        }]; 
    
        return cell; 
    } 
    

Mais quand je le lance et faites défiler la UICollectionView assez vite, je trouve l'utilisation de la mémoire devient raide comme ceci:

memory use

Comment puis-je réduire en cas il planterait lorsque la mémoire ne suffit pas?

+0

Je m'attendrais à ce genre de motif, car avant que PhotoKit puisse créer la vignette, il doit charger toute l'image en mémoire. Aussi, testez-vous sur des appareils ou dans le simulateur? Le comportement de la mémoire sera très différent entre les deux, donc testez toujours sur l'appareil pour obtenir une image réaliste des performances de vos applications. –

+0

Je suis toujours tester sur l'appareil qui est mon iPhone 6 Plus. – Boris

Répondre

3

Ce que je l'ai fait est maintenant

  1. Réduire la taille cible des objets récupérés PHAsset;
  2. Essayez d'adopter la mise en cache. Mon code est comme ci-dessous:

    CGFloat scale = 1.5; //or an even smaller one 
    if (!_manager) { 
        _manager = [[PHCachingImageManager alloc] init]; 
    } 
    if (!_options) { 
        _options = [[PHImageRequestOptions alloc] init]; 
    } 
    _options.resizeMode = PHImageRequestOptionsResizeModeExact; 
    _options.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic; 
    
    NSRange range = NSMakeRange(0, _fetchedPhotos.count); 
    NSIndexSet *set = [NSIndexSet indexSetWithIndexesInRange:range]; 
    NSArray *assets = [_fetchedPhotos objectsAtIndexes:set]; 
    
    CGSize targetSize = CGSizeMake(_layout.itemSize.width*scale, _layout.itemSize.height*scale); 
    
    [_manager startCachingImagesForAssets:assets targetSize:targetSize contentMode:PHImageContentModeAspectFill options:_options]; 
    

Maintenant même je fais défiler la UICollectionView assez vite, la mémoire supérieure serait inférieure à 50 MB, et grâce à Caching (je suppose qu'il fonctionne basé sur mon code), il ne fluctue pas beaucoup, l'utilisation de la mémoire est comme ceci:

better memory use

MISE à JOUR Selon un autre poste here, il est recommandé de ne pas spécifier PHImageRequestOptions objet. Au lieu de cela, vous pouvez laisser à iOS le soin de décider ce qui vous convient le mieux pour présenter les photos avec la meilleure qualité et le moins de temps possible.

+0

Vous pouvez accepter vos propres réponses – markhunte

0

Je suggère de regarder la réponse que j'ai mentionnée here. Non seulement cela vous aiderait avec la mise en cache, mais l'exemple du cadre Photos par Apple vous aiderait à résoudre tous les problèmes.