Ios 如何使用PhotoKit减少内存使用?
我正在使用Ios 如何使用PhotoKit减少内存使用?,ios,objective-c,photokit,Ios,Objective C,Photokit,我正在使用PhotoKit从系统相册中获取照片,并将其放入UICollectionView中 对于UICollectionViewCell,我将其设置为: cell.imageView.contentMode = UIViewContentModeScaleAspectFill; -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPa
PhotoKit
从系统相册中获取照片,并将其放入UICollectionView
中
UICollectionViewCell
,我将其设置为:
cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
-(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
时,我仅从collection
中获取照片PHAsset
:摄像机卷
:
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];
}
}];
PHFetchResult
请求UIImage
,如下所示:
cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
-(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
时,我发现内存使用变得如此急剧:
cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
-(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;
}
如果内存不足,它会崩溃,我如何减少它呢?我现在所做的是
PHAsset
对象的目标大小李>
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
,顶部内存也将小于50MB
,多亏了缓存
(我猜它是基于我的代码工作的),它的波动性不会太大,内存使用如下:
cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
-(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;
}
更新
根据另一篇帖子,建议不要指定
PHImageRequestOptions
对象。相反,你可以让iOS来决定什么是最适合你的,以最好的质量和最短的时间展示照片。我建议你看看我提到的答案。这不仅可以帮助您进行缓存,苹果的照片框架示例也可以帮助您解决任何问题。我期望这种模式,因为在PhotoKit创建缩略图之前,它必须将整个图像加载到内存中。另外,您是在设备上测试还是在模拟器中测试?两者之间的内存行为会有很大的不同,所以总是在设备上测试,以获得应用程序性能的真实图片。我总是在我的iPhone 6 Plus设备上测试它。