SGImageCache
一个轻量级的 iOS 图像和数据缓存,带有内置队列管理。
CocoaPods 设置
pod 'SGImageCache'
典型用法
- 尝试立即从缓存中加载图像,如果存在的话
- 如果图像不在缓存中,则异步获取图像。
- (可选)还建议使用 UIView 转换动画来实现视图的渐变效果。
// Swift
if let image = SGImageCache.image(forURL: url) {
imageView.image = image // image loaded immediately from cache
} else {
SGImageCache.getImage(url: url) { [weak self] image in
self?.imageView.image = image // image loaded async
}
}
// Objective-C
if ([SGImageCache haveImageForURL:url]) {
self.imageView.image = [SGImageCache imageForURL:url]; // image loaded immediately from cache
} else {
__weak UIViewController *me = self;
[SGImageCache getImageForURL:url].then(^(UIImage *image) {
me.imageView.image = image; // image loaded async
});
}
高级用法
紧急获取图像
// Objective-C
[SGImageCache getImageForURL:url].then(^(UIImage *image) {
if (image) {
self.imageView.image = image;
}
});
// Swift
SGImageCache.getImage(url: url) { [weak self] image in
guard let self = self else { return }
self.imageView.image = image
}
这将把获取请求添加到fastQueue
(一个并行队列)。所有图像获取(无论是从内存、磁盘还是远程)都在主线程之外执行。
按需队列图像获取请求
// Objective-C
[SGImageCache slowGetImageForURL:url];
// Swift
SGImageCache.slowGetImage(url: url)
这将把获取请求添加到slowQueue
(一个序列队列)。所有图像获取(无论是从内存、磁盘还是远程)都在主线程之外执行。
将图像获取任务添加到slowQueue
对于预取屏幕外内容非常有用。例如,如果您有100行表格数据,但一次只显示3行,您将使用getImageForURL:
从fastQueue
请求屏幕上的行的图像,并将其余图像添加到slowQueue
中,使用slowGetImageForURL:
。
通知缓存紧急图像获取不再紧急
// Objective-C
[SGImageCache moveTaskToSlowQueueForURL:url];
// Swift
SGImageCache.moveTaskToSlowQueueForURL(url)
这对于使已滚动出屏幕的内容的图像获取降优先级很有用。该内容可能稍后还会滚动到屏幕上,因此您仍然希望执行获取,但它不再紧急需要。
远程获取失败或重试时进行操作
// Objective-C
SGCachePromise *promise = [SGImageCache getImageForURL:url];
promise.then(^(UIImage *image) {
self.imageView.image = image;
});
promise.onRetry = ^{
// Called when SGImageCache automatically retries
// fetching the image due to a reachability change.
[self showLoadingSpinner];
};
promise.onFail = ^(NSError *error, BOOL fatal) {
// If the failure was fatal, SGImageCache will not
// automatically retry (eg. from a 404)
[self displayError:error];
};
// Swift
let promise = SGImageCache.getImageForURL(url)
promise.swiftThen({object in
if let image = object as? UIImage {
self.imageView.image = image
}
return nil
})
promise.onRetry = {
self.showLoadingSpinner()
}
promise.onFail = { (error: NSError?, wasFatal: Bool) -> () in
self.displayError(error)
}
这在显示网络故障状态、在可访问性更改时显示加载指示器或任何可能需要通知无法获取图像的其他功能时很有用。
fastQueue
fastQueue
是一个并行队列,用于紧急需要的图片。getImageForURL:
方法向此队列添加任务。并行任务的最大数量由 iOS 管理,基于设备的处理器数量和其他因素。
slowQueue
slowQueue
是一个串行队列,用于预取将来可能需要的图片(例如,用于当前屏幕外的内容)。slowGetImageForURL:
方法向此队列添加任务。
slowQueue
在 fastQueue
活跃时会自动暂停,以避免在紧急图片抓取过程中消耗网络带宽。一旦所有的 fastQueue
任务完成,slowQueue
将会恢复。
任务去重
如果对同一个 URL 请求了图片,而该图片已经排队或正在处理,SGImageCache
会复用现有的任务,并在必要时将其从 slowQueue
移动到 fastQueue
,具体取决于使用了哪种图片抓取方法。这确保了每个 URL 只会有一个网络请求,无论请求了多少次。
内存警告智能释放图片
如果您使用 SGImageView
而不是 UIImageView
,并且通过 setImageForURL:
中的一个方法加载图片,屏幕外的图像视图将在内存警告时释放它们的 image
,并在图像视图返回屏幕时从缓存中恢复它们。这允许屏幕外的但仍存在的视图控制器(例如 nav 控制器堆栈中的上一个控制器)释放否则会被不必要保留的内存,并减少在内存有限的情况下应用程序被 iOS 终止的机会。
Generic caching of NSData
您可以使用SGImageCache来缓存以NSData对象形式存在的通用数据(如PDFs,JSON有效载荷)。只需使用与SGImageCache等效的SGCache
类方法即可,而不是SGImageCache的方法。
// Objective-C
[SGCache getFileForURL:url].then(^(NSData *data) {
// do something with data
});
// Swift
SGCache.getFileForURL(url).swiftThen({object in
if let data = object as? NSData {
// do something with data
}
return nil
})