面试题答案
一键面试使用NSURLSession加载图片
- 创建NSURLSession对象:
可以通过
NSURLSession
的类方法创建一个NSURLSession
对象。通常使用默认配置创建会话,如下:NSURLSession *session = [NSURLSession sharedSession];
- 创建NSURLRequest:
构建一个指向图片资源的
NSURLRequest
。假设图片的URL为imageURL
:NSURL *imageURL = [NSURL URLWithString:@"https://example.com/image.jpg"]; NSURLRequest *request = [NSURLRequest requestWithURL:imageURL];
- 发起数据任务:
使用
NSURLSession
发起一个数据任务来加载图片数据。NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (!error && data) { UIImage *image = [UIImage imageWithData:data]; // 在这里可以将image应用到UI上,如UIImageView } }]; [dataTask resume];
内存优化
- 分段加载:
可以使用
NSURLSessionDownloadTask
来分段下载图片数据,而不是一次性加载全部数据到内存。NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (!error && location) { NSData *data = [NSData dataWithContentsOfURL:location]; UIImage *image = [UIImage imageWithData:data]; } }]; [downloadTask resume];
- 图片处理:
- 按需加载:只在需要显示图片时才加载,避免提前加载过多图片到内存。
- 尺寸适配:根据显示图片的控件大小,对加载后的图片进行尺寸调整,减少内存占用。例如,若要在
UIImageView
中显示图片,可以使用如下方法调整图片大小:
- (UIImage *)resizeImage:(UIImage *)image toSize:(CGSize)size { UIGraphicsBeginImageContextWithOptions(size, NO, 0.0); [image drawInRect:CGRectMake(0, 0, size.width, size.height)]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; }
- 缓存机制:
- 内存缓存:可以使用
NSCache
来实现简单的内存缓存。在加载图片前先检查缓存中是否已有该图片,若有则直接使用缓存中的图片,避免重复加载。
static NSCache *imageCache; + (void)initialize { if (self == [YourViewController class]) { imageCache = [[NSCache alloc] init]; } } - (UIImage *)loadImageFromURL:(NSURL *)url { UIImage *cachedImage = [imageCache objectForKey:url]; if (cachedImage) { return cachedImage; } // 这里进行正常的图片加载逻辑,加载完成后将图片存入缓存 NSData *data = [NSData dataWithContentsOfURL:url]; UIImage *image = [UIImage imageWithData:data]; [imageCache setObject:image forKey:url]; return image; }
- 磁盘缓存:使用第三方库如
SDWebImage
或AFNetworking
的图片加载功能,它们自带磁盘缓存机制,可以有效减少重复下载图片,降低内存峰值。
- 内存缓存:可以使用