gpt4 book ai didi

iphone - 从磁盘加载图像时的 ScrollView 和表格 View 性能

转载 作者:行者123 更新时间:2023-12-03 18:47:08 25 4
gpt4 key购买 nike

我正在尝试通过使用基于磁盘的图像缓存而不是通过网络来提高图像密集型 iPhone 应用程序的性能。我在 SDImageCache ( http://github.com/rs/SDWebImage/blob/master/SDImageCache.m ) 之后对图像缓存进行了建模,并且几乎相同,但没有异步缓存输入/输出操作。

我有一些 ScrollView 和表格 View 可以异步加载这些图像。如果图像在磁盘上,则从图像缓存中加载,否则发出网络请求,并将后续结果存储在缓存中。

我遇到的问题是,当我滚动 ScrollView 或表格 View 时,从磁盘加载图像时会出现明显的延迟。特别是,在 ScrollView 上从一个页面转到另一个页面的动画在过渡过程中有一个小卡住。

我尝试通过以下方式解决此问题:

  • 使用 NSOperationQueue 和 NSInitationOperation 对象发出磁盘访问请求(与 SDImageCache 的方式相同),但这对解决延迟没有任何帮助。
  • 调整 ScrollView Controller 代码,以便仅在 ScrollView 不再滚动时加载图像。这意味着仅当 ScrollView 停止滚动时才会触发磁盘访问,但如果我立即尝试滚动到下一页,我会注意到从磁盘加载图像时存在滞后。

有没有办法让我的磁盘访问性能更好或对 UI 的影响更小?

请注意,我也已经将图像缓存在内存中。因此,一旦所有内容都加载到内存中,用户界面就会变得漂亮且响应灵敏。但是,当应用启动时,或者发出内存不足警告时,当从磁盘加载图像时,我会遇到许多 UI 延迟。

相关代码片段如下。我不认为我在做任何奇特或疯狂的事情。这种延迟在 iPhone 3G 上似乎并不明显,但在第二代 iPod Touch 上则相当明显。

图像缓存代码:

这是我的图像缓存代码的相关片段。非常简单。

- (BOOL)hasImageDataForURL:(NSString *)url {
return [[NSFileManager defaultManager] fileExistsAtPath:[self cacheFilePathForURL:url]];
}

- (NSData *)imageDataForURL:(NSString *)url {
NSString *filePath = [self cacheFilePathForURL:url];

// Set file last modification date to help enforce LRU caching policy
NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
[attributes setObject:[NSDate date] forKey:NSFileModificationDate];
[[NSFileManager defaultManager] setAttributes:attributes ofItemAtPath:filePath error:NULL];

return [NSData dataWithContentsOfFile:filePath];
}

- (void)storeImageData:(NSData *)data forURL:(NSString *)url {
[[NSFileManager defaultManager] createFileAtPath:[self cacheFilePathForURL:url] contents:data attributes:nil];
}

ScrollView Controller 代码

这是我用于在 ScrollView Controller 中显示图像的相关代码片段。

- (void)scrollViewDidScroll:(UIScrollView *)theScrollView {
CGFloat pageWidth = theScrollView.frame.size.width;
NSUInteger index = floor((theScrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;

[self loadImageFor:[NSNumber numberWithInt:index]];
[self loadImageFor:[NSNumber numberWithInt:index + 1]];
[self loadImageFor:[NSNumber numberWithInt:index - 1]];
}

- (void)loadImageFor:(NSNumber *)index {
if ([index intValue] < 0 || [index intValue] >= [self.photoData count]) {
return;
}

// ... initialize an image loader object that accesses the disk image cache or makes a network request

UIView *iew = [self.views objectForKey:index];
UIImageView *imageView = (UIImageView *) [view viewWithTag:kImageViewTag];
if (imageView.image == nil) {
NSDictionary *photo = [self.photoData objectAtIndex:[index intValue]];
[loader loadImage:[photo objectForKey:@"url"]];
}
}

图像加载器对象只是一个轻量级对象,它检查磁盘缓存并决定是否从磁盘或网络获取图像。完成后,它会调用 ScrollView Controller 上的方法来显示图像:

- (void)imageLoadedFor:(NSNumber *)index image:(UIImage *)image {
// Cache image in memory
// ...

UIView *view = [self.views objectForKey:index];
UIImageView *imageView = (UIImageView *) [view viewWithTag:kImageViewTag];
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.image = image;
}

更新

我正在试验该应用程序,我禁用了图像缓存并恢复为始终发出网络请求。看起来,在滚动 ScrollView 和表格 View 时,简单地使用网络请求来获取图像也会导致相同的延迟!也就是说,当网络请求完成并且图像显示在 ScrollView 页面或表格单元格中时,UI 会稍微滞后一点,并且当我尝试拖动它时会出现几秒钟的滞后。

使用磁盘缓存时,延迟似乎更加明显,因为延迟总是发生在页面转换时。也许我在将加载的图像分配给适当的 UIImageView 时做错了什么?

另外 - 我尝试使用小图像(50x50 缩略图),延迟似乎有所改善。因此,性能下降似乎是由于从磁盘加载大图像或将大图像加载到 UIImage 对象中造成的。我想一项改进是减少加载到 ScrollView 和表格 View 中的图像的大小,这正是我计划做的。但是,我只是不明白其他照片密集型应用程序如何能够在可 ScrollView 中呈现看起来非常高分辨率的照片,而不会因存储到磁盘或通过网络而出现性能问题。

最佳答案

您应该查看 LazyTableImages 示例应用程序。

关于iphone - 从磁盘加载图像时的 ScrollView 和表格 View 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3756863/

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