gpt4 book ai didi

performance - 设置 UIImageView 的图像属性会导致严重滞后

转载 作者:行者123 更新时间:2023-12-03 11:32:50 24 4
gpt4 key购买 nike

让我告诉你我遇到的问题以及我如何尝试解决它。我有一个 UIScrollView 加载 subview 作为一个从左到右滚动。每个 subview 有 10-20 个图像,每个图像大约 400x200。当我从一个 View 滚动到另一个 View 时,我遇到了相当多的滞后。

经过调查,我发现在卸载所有 View 并再次尝试后,延迟消失了。我认为图像的同步缓存是导致延迟的原因。所以我创建了一个 UIImageView 的子类,它异步加载图像。加载代码如下所示(self.dispatchQueue 返回一个串行调度队列)。

- (void)loadImageNamed:(NSString *)name {
dispatch_async(self.dispatchQueue, ^{
UIImage *image = [UIImage imageNamed:name];

dispatch_sync(dispatch_get_main_queue(), ^{
self.image = image;
});
});
}

但是,在将所有 UIImageViews 更改为这个子类后,我仍然遇到滞后(我不确定它是否减少了)。我把问题的原因归结为 self.image = image; .为什么这会导致如此多的延迟(但仅在第一次加载时)?

请帮我。 =(

最佳答案

编辑 3:iOS 15 现在提供 UIImage.prepareForDisplay(completionHandler:) .

image.prepareForDisplay { decodedImage in
imageView.image = decodedImage
}
或者
imageView.image = await image.byPreparingForDisplay()

编辑 2:这是一个包含一些改进的 Swift 版本。 (未经测试。)
https://gist.github.com/fumoboy007/d869e66ad0466a9c246d

编辑:实际上,我相信所有必要的是以下内容。 (未经测试。)
- (void)loadImageNamed:(NSString *)name {
dispatch_async(self.dispatchQueue, ^{
// Determine path to image depending on scale of device's screen,
// fallback to 1x if 2x is not available
NSString *pathTo1xImage = [[NSBundle mainBundle] pathForResource:name ofType:@"png"];
NSString *pathTo2xImage = [[NSBundle mainBundle] pathForResource:[name stringByAppendingString:@"@2x"] ofType:@"png"];

NSString *pathToImage = ([UIScreen mainScreen].scale == 1 || !pathTo2xImage) ? pathTo1xImage : pathTo2xImage;


UIImage *image = [[UIImage alloc] initWithContentsOfFile:pathToImage];

// Decompress image
if (image) {
UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);

[image drawAtPoint:CGPointZero];

image = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();
}


// Configure the UI with pre-decompressed UIImage
dispatch_async(dispatch_get_main_queue(), ^{
self.image = image;
});
});
}

原始答案:事实证明它不是 self.image = image;直接地。 UIImage 图像加载方法不会立即解压缩和处理图像数据;他们在 View 刷新显示时执行此操作。所以解决方案是降低到 Core Graphics 的级别,并自己解压和处理图像数据。新代码如下所示。
- (void)loadImageNamed:(NSString *)name {
dispatch_async(self.dispatchQueue, ^{
// Determine path to image depending on scale of device's screen,
// fallback to 1x if 2x is not available
NSString *pathTo1xImage = [[NSBundle mainBundle] pathForResource:name ofType:@"png"];
NSString *pathTo2xImage = [[NSBundle mainBundle] pathForResource:[name stringByAppendingString:@"@2x"] ofType:@"png"];

NSString *pathToImage = ([UIScreen mainScreen].scale == 1 || !pathTo2xImage) ? pathTo1xImage : pathTo2xImage;


UIImage *uiImage = nil;

if (pathToImage) {
// Load the image
CGDataProviderRef imageDataProvider = CGDataProviderCreateWithFilename([pathToImage fileSystemRepresentation]);
CGImageRef image = CGImageCreateWithPNGDataProvider(imageDataProvider, NULL, NO, kCGRenderingIntentDefault);


// Create a bitmap context from the image's specifications
// (Note: We need to specify kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little
// because PNGs are optimized by Xcode this way.)
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef bitmapContext = CGBitmapContextCreate(NULL, CGImageGetWidth(image), CGImageGetHeight(image), CGImageGetBitsPerComponent(image), CGImageGetWidth(image) * 4, colorSpace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little);


// Draw the image into the bitmap context
CGContextDrawImage(bitmapContext, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image);

// Extract the decompressed image
CGImageRef decompressedImage = CGBitmapContextCreateImage(bitmapContext);


// Create a UIImage
uiImage = [[UIImage alloc] initWithCGImage:decompressedImage];


// Release everything
CGImageRelease(decompressedImage);
CGContextRelease(bitmapContext);
CGColorSpaceRelease(colorSpace);
CGImageRelease(image);
CGDataProviderRelease(imageDataProvider);
}


// Configure the UI with pre-decompressed UIImage
dispatch_async(dispatch_get_main_queue(), ^{
self.image = uiImage;
});
});
}

关于performance - 设置 UIImageView 的图像属性会导致严重滞后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10790183/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com