如何使用PhotoKit减少内存使用?

时间:2015-09-07 03:06:36

标签: ios objective-c photokit

我正在使用PhotoKit从系统相册中提取照片并将其放入UICollectionView

  1. 对于UICollectionViewCell,我设置如下:

    cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
    
  2. 在初始化UICollectionView时,我仅从PHAssetcollection获取照片Camera Roll

    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. 然后我从上方UIImage请求PHFetchResult,如下所示:

    -(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;
    }
    
  4. 但是当我运行它并快速滚动UICollectionView时,我发现内存使用变得如此陡峭:

    memory use

    如果在内存不足时会崩溃,我该如何减少它?

2 个答案:

答案 0 :(得分:3)

我现在所做的是

  1. 减少已提取的PHAsset个对象的目标大小;
  2. 尝试采用缓存。我的代码如下:

    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];
    
  3. 现在即使我足够快地滚动UICollectionView,顶部内存也会小于50 MB,并且感谢Caching(我猜它基于我的代码工作)它没有& #39; t波动那么多,内存使用是这样的:

    better memory use

    <强>更新 根据另一篇文章here,建议不要指定PHImageRequestOptions个对象。相反,您可以将它留给iOS来决定哪种方式能够以最佳质量和最短时间呈现照片。

答案 1 :(得分:0)

我建议看看我提到的答案here。这不仅可以帮助您进行缓存,而且Apple提供的Photos Framework示例可以帮助您解决任何问题。