我有一个应用程序可以下载几张图像并将它们存储在手机上。总共可能需要大约20个图像上衣。我需要能够根据用户所在的屏幕随意检索这些图像。这些图像将无限期存储,因此我不想使用临时目录。
目前我有一个名为Images的类,这些方法
- (void) cacheImage: (NSString *) ImageURLString : (NSString *)imageName
{
NSURL *ImageURL = [NSURL URLWithString: ImageURLString];
// Generate a unique path to a resource representing the image you want
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex: 0];
NSString *docFile = [docDir stringByAppendingPathComponent: imageName];
// Check for file existence
if(![[NSFileManager defaultManager] fileExistsAtPath: docFile])
{
// The file doesn't exist, we should get a copy of it
// Fetch image
NSData *data = [[NSData alloc] initWithContentsOfURL: ImageURL];
UIImage *image = [[UIImage alloc] initWithData: data];
// Is it PNG or JPG/JPEG?
// Running the image representation function writes the data from the image to a file
if([ImageURLString rangeOfString: @".png" options: NSCaseInsensitiveSearch].location != NSNotFound)
{
[UIImagePNGRepresentation(image) writeToFile: docFile atomically: YES];
}
else if([ImageURLString rangeOfString: @".jpg" options: NSCaseInsensitiveSearch].location != NSNotFound ||
[ImageURLString rangeOfString: @".jpeg" options: NSCaseInsensitiveSearch].location != NSNotFound)
{
[UIImageJPEGRepresentation(image, 100) writeToFile: docFile atomically: YES];
}
}
}
- (UIImage *) getCachedImage : (NSString *)imageName
{
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString* cachedPath = [documentsDirectory stringByAppendingPathComponent:imageName];
UIImage *image;
// Check for a cached version
if([[NSFileManager defaultManager] fileExistsAtPath: cachedPath])
{
image = [UIImage imageWithContentsOfFile: cachedPath]; // this is the cached image
}
else
{
NSLog(@"Error getting image %@", imageName);
}
return image;
}
-(void)getImages
{
//example
NSString *image1URL = @"http://test/image1.png";
NSString *image2URL = @"http://test/image2.png";
NSString *image3URL = @"http://test/image3.png";
[self cacheImage:sLogo: @"Image1"];
[self cacheImage:sBlankNav: @"Image2"];
[self cacheImage:buttonLarge :@"Image3"];
}
-(void) storeImages
{
image1 = [self getCachedImage:@"Image1"];
image2 = [self getCachedImage:@"Image2"];
image3 = [self getCachedImage:@"Image3"];
}
所以我使用这样的代码
Images *cache = [[Images alloc]init];
[cache storeImages];
当应用程序第一次开始获取图像时,会调用get images方法,之后不再调用它,除非服务器上的图像已更新,我需要检索更新的图像。
代码有效,但问题是当我导航到使用它的屏幕时,在加载图像时加载屏幕之前会有一点点延迟。
我的应用程序是一个选项卡式应用程序,因此它从选项卡1开始,我单击实现代码的选项卡2,第一次加载时会有轻微的暂停。它不会持续很长时间,但它很明显,非常烦人。之后它很好,因为它已经加载。但是对于导航控制器,每次从第一个VC移动到第二个VC时,都会再次调用该方法,因此每次导航时都会出现延迟。
图像不是很大,最大的图像是68kb,其他图像小得多。目前我只测试了5张图片。是否有更有效的存储和检索图像的方法,或者我的代码是否有问题?我需要能够在没有任何明显延迟的情况下检索这些图像,以使我的应用程序保持流畅而不生涩或笨重。
提前致谢!!
答案 0 :(得分:1)
因为您正在同步下载数据而导致延迟
// NSData *data = [[NSData alloc] initWithContentsOfURL: ImageURL];
尝试一些像SDWebImage这样的智能库: 它允许您在仍然可以显示本地图像(代理图像)的同时异步下载图像。顺便说一下,你仍然可以免费获得缓存图像。所以即使你在本地,你仍然可以捕获以前下载的图像
https://github.com/rs/SDWebImage
必须有
答案 1 :(得分:1)
您有两个选项可以在后台线程上执行图片加载工作 - 使用Grand Central Dispatch或NSInvocationOperation。 GCD可能被认为是两者的清洁工:
dispatch_queue_t q = dispatch_get_global_queue(0, 0);
dispatch_queue_t main = dispatch_get_main_queue();
dispatch_async(q, ^{
//load images here
dispatch_async(main, ^{
// show on main thread here
});
});