3

システムアルバムから写真をPhotoKit取得してUICollectionView.

  1. の場合、次のUICollectionViewCellように設定します。

    cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
    
  2. my を初期化するとき、次からUICollectionView写真を取得します:のみ:PHAssetcollectionCamera 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;
    }
    

しかし、それを実行してUICollectionView十分に速くスクロールすると、メモリ使用量が次のように急激になることがわかりました。

メモリ使用量

メモリが足りないときにクラッシュする場合に備えて、どうすればそれを減らすことができますか?

4

2 に答える 2

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];
    

今でもUICollectionView十分に速くスクロールしても、トップメモリ​​は 未満50 MBになり、Caching(コードに基づいて動作していると思います)それほど変動しないため、メモリ使用量は次のようになります。

より良いメモリ使用

更新ここ の別の投稿によると、オブジェクトを指定しないことをお勧めしますPHImageRequestOptions。代わりに、iOS に任せて、写真を最高の品質で最短の時間で表示するのに最適なものを決定することができます.

于 2015-09-07T07:42:54.990 に答える
0

ここで言及した答えを見ることをお勧めします。これはキャッシングに役立つだけでなく、apple による Photos Framework の例は、あらゆる問題を解決するのに役立ちます。

于 2015-09-24T06:12:34.877 に答える