高级摘要:我想用更高质量的版本替换相当低分辨率的 ALAsset 组图像[group posterImage],以便它们可以在屏幕上显示得更大。通常我会根据界面的需要加载它们,但是[ALAssetsGroup enumerateAssetsAtIndexes]非常慢。(我可以预加载比可见的 x 量更宽,并且可能仍然这样做,但这似乎比它的价值更麻烦,并且仍然受到响应缓慢的影响,尤其是在 iOS5 中)
我认为我可以做的是请求每个组中的第一个资产,然后对其进行缩放,存储结果。然而,即使考虑到更大尺寸的图像,我对正在发生的内存分配感到惊讶。使用 VM Tracker,我看到大量 CGImage 分配以及我正在创建的“映射文件”缩略图。我正在使用 ARC,所以我预计原始的大图像会丢失,但我的 VM Tracker 结果并没有显示出来。
如果我使用默认的posterImage实现,我的 Resident Mem ~= 30mb,Dirty Mem ~= 80mb 和 Virtual tops ~240mb(本身很大)。每个分配分析器的“实时”< 10mb。
如果我改用下面的代码,我会在加载 150 个图像中的第 80 个图像时崩溃。那时我的 Resident Mem > 480mb,Dirty Mem > 420mb 和 Virtual 高达 750mb。显然这是站不住脚的。
这是我在 NSOperationQueue 内部使用的代码,用于获取每个组的第一张图像以用作高分辨率海报图像。
NSIndexSet* i = [NSIndexSet indexSetWithIndex:0];
ALAssetsGroupEnumerationResultsBlock assetsEnumerationBlock = ^(ALAsset *result, NSUInteger i, BOOL *stop) {
if (result) {
// pull the full resolution image and then scale it to fit our desired area
ALAssetRepresentation *assetRepresentation = [result defaultRepresentation];
CGImageRef ref = [assetRepresentation fullScreenImage];
CGFloat imgWidth = CGImageGetWidth(ref);
CGFloat imgHeight = CGImageGetHeight(ref);
CGFloat minDimension = MIN(imgWidth,imgHeight);
// grab a square subset of the image, centered, to use
CGRect subRect = CGRectMake(0, 0, minDimension, minDimension);
subRect.origin = CGPointMake(imgWidth / 2 - minDimension / 2, imgHeight / 2 - minDimension / 2);
CGImageRef squareRef = CGImageCreateWithImageInRect(ref,subRect);
// now scale it down to fit
CGFloat heightScale = dimension / minDimension;
UIImage* coverImage = [UIImage imageWithCGImage:squareRef scale:1/heightScale orientation:UIImageOrientationUp];
if (coverImage) {
[mainViewController performSelectorOnMainThread:@selector(imageDidLoad:)
withObject:[NSArray arrayWithObjects:coverImage, [NSNumber numberWithInt:photoIndex], nil]
waitUntilDone:NO];
}
CGImageRelease(squareRef);
// DO NOT RELEASE 'ref' it will be 'zombied' as it is already handled by the system
//CGImageRelease(ref);
*stop = YES;
}
else {
// default image grab....
}
};
[group enumerateAssetsAtIndexes:i options:NSEnumerationConcurrent usingBlock:assetsEnumerationBlock];
我是在上面做错了什么,还是我只是加载所有图像不聪明?我想得越多,我就越认为加载可见图像窗口加上它周围的缓冲区是要走的路,但我想了解更多关于我可能在上面的代码中做错了什么。谢谢!