[翻译] AsyncImageView 异步下载图片
AsyncImageView
https://github.com/nicklockwood/AsyncImageView
AsyncImageView is a simple extension of UIImageView for loading and displaying images asynchronously on iOS so that they do not lock up the UI.
AsyncImageView是关于UIImageView的扩展,用来异步加载和显示图片防止阻塞UI。
Purpose(目的)
AsyncImageView includes both a simple category on UIImageView for loading and displaying images asynchronously on iOS so that they do not lock up the UI, and a UIImageView subclass for more advanced features. AsyncImageView works with URLs so it can be used with either local or remote files.
Loaded/downloaded images are cached in memory and are automatically cleaned up in the event of a memory warning. The AsyncImageView operates independently of the UIImage cache, but by default any images located in the root of the application bundle will be stored in the UIImage cache instead, avoiding any duplication of cached images.
The library can also be used to load and cache images independently of a UIImageView as it provides direct access to the underlying loading and caching classes.
AsyncImageView包含了两种类型,一种是UIImageView的类目,用来异步加载以及显示图片的。另一种是UIImageView的子类,含有更多的一些特性。AsyncImageView 通过URL来工作,所以,既可以是本地的图片,也可以是网络上的图片。加载和下载图片是缓存在内存的,所以当出现内存警告时会自动删除内存中的图片。AsyncImageView 独立于UIImage的缓存操作,但是默认的是,任何在bundle中的图片都被缓存起来了,防止重复的缓存图片。
Supported OS & SDK Versions(支持OS&SDK的版本)
- Supported build target - iOS 7.1 (Xcode 5.1, Apple LLVM compiler 5.1)
- Earliest supported deployment target - iOS 5.0
- Earliest compatible deployment target - iOS 4.3
- 支持iOS 7.1
- 支持早期的 iOS 5.0
- 兼容更早期的 iOS 4.3
NOTE: 'Supported' means that the library has been tested with this version. 'Compatible' means that the library should work on this iOS version (i.e. it doesn't rely on any unavailable SDK features) but is no longer being tested for compatibility and may require tweaking or bug fixes to run correctly.
注意:支持意味着这个库已经在那个版本上测试过了。兼容意味着这个库应该能在那个版本上运行,但以后不会在那个版本上测试,更不会修复那本版本中存在的bug。
ARC Compatibility(ARC情况)
As of version 1.5, AsyncImageView requires ARC. If you wish to use AsyncImageView in a non-ARC project, just add the -fobjc-arc compiler flag to the AsyncImageView.m file. To do this, go to the Build Phases tab in your target settings, open the Compile Sources group, double-click AsyncImageView.m in the list and type -fobjc-arc into the popover.
If you wish to convert your whole project to ARC, comment out the #error line in AsyncImageView.m, then run the Edit > Refactor > Convert to Objective-C ARC... tool in Xcode and make sure all files that you wish to use ARC for (including AsyncImageView.m) are checked.
从1.5版本开始,AsyncImageView需要开ARC,如果你想将AsyncImageView用在非ARC的项目中,添加编译标签 -fobjc-arc 在AsyncImageView.m 文件上。到Bulid Phases 选项卡上找到你的目标文件,打开 Complile Sources 组,双击 AsyncImageView.m 文件,键入 -fobjc-arc 即可。
如果你想将你整个项目都转换成ARC,注释掉含有 #error 的行,然后,运行 Edit>Refactor>Convert to Objective-C ARC... 工具,确保所有要转换成ARC的文件都检查过了而没有遗漏。
Thread Safety(线程安全)
AsyncImageView uses threading internally, but none of the AsyncImageView external interfaces are thread safe, and you should not call any methods or set any properties on any of the AsyncImageView classes except on the main thread.
AsyncImageView 本质上使用了线程,但没有哪个AsyncImageView是线程安全的,你不能设置任何的相关线程的属性,除非在主线程上。
Installation(安装)
To use the AsyncImageView in an app, just drag the AsyncImageView class files into your project.
仅需将AsyncImageView 文件夹拖入到你的工程项目中即可。
Categories(类目文件)
The basic interface of AsyncImageView is a category that extends UIImageView with the following property:
AsyncImageView 最主要的接口是扩展了一个属性(扩展了一个属性?????)
@property (nonatomic, strong) NSURL *imageURL;
Upon setting this property, AsyncImageView will begin loading/downloading the specified image on a background thread. Once the image file has loaded, the UIImageView's image property will be set to the resultant image. If you set this property again while the previous image is still loading then the images will be queued for loading in the order in which they were set.
通过设置这个属性,AsyncImageView 将会开始在指定的线程中下载加载指定的图片。当这张图片加载完成后,这个image的属性就会被设置成合成的image,如果此时,你再一次设置了这个属性,那么,之前加载的图片还在,然而,新指定的图片将会进入队列中按照顺序来加载。
This means that you can, for example, set a UIImageView to load a small thumbnail image and then immediately set it to load a larger image and the thumbnail image will still be loaded and set before the larger image loads.
这意味着,你可以,设置了一张不清晰的图片,然后你再设置着去加载清晰的图片,只不过,图片加载完成后,不清晰的图片被清晰的图片覆盖住了。
If you access this property it will return the most recent image URL set for the UIImageView, which may not be the next one to be loaded if several image URLs have been queued on that image view. If you wish to cancel the previously loading image, use the -cancelLoadingURL:target:
method on the AsyncImageLoader class, passing the UIImageView instance as the target (see below).
如果你用了这个属性设置了很多图片,他将会返回你设置过的那些图片的 URL 地址,但是并不一定按照你指定的顺序来加载(因为是并发线程嘛),如果你想取消当前加载中的图片,使用-cancelLoadingURL:target:方法来取消,给UIImageView的一个实例对象使用该方法。
Classes(类)
AsyncImageView includes an AsyncImageView class, which is a subclass of UIImageView. This implements some useful features on top of the UIImageView category, including the automatic display of a loading spinner, and a nice crossfade effect when the image loads.
AsyncImageView also provides an AsyncImageLoader class for advanced users. AsyncImageLoader manages the loading/downloading and queueing of image requests. Set properties of the shared loader instance to control loading behaviour, or call its loading methods directly to preload images off-screen.
AsyncImageView库包含了一个AsyncImageView的类,它继承至UIImageView.这个类实现了很多有用的特性,如自动显示一个加载的指示器,以及当图片下载完成后加载时会出现一个渐隐出现的效果.
AsyncImageView也提供了一个AsyncImageLoader类,给高端用户使用.AsyncImageLoader管理着加载下载以及队列图片的请求.设置共享加载的实例变量来达到控制下载行为的目的,或者,直接预加载图片即可.
AsyncImageView properties(相关属性)
The AsyncImageView class has the following properties:
AsyncImageView有着如下的一些属性:
@property (nonatomic, assign) BOOL showActivityIndicator;
If YES, the AsyncImageView will display a loading spinner when the imageURL is set. This will automatically hide once the image has loaded. Note that this value should bet set before setting the imageURL. Setting this value when loading is already in progress will have no effect. Defaults to YES.
如果设置成YES,AsyncImageView在加载一个网络的image时会显示一个加载的菊花,如果image加载完成后,菊花将会消失.注意,你需要在进行网络请求之前设置这个值.之后设置的话没有效果了,默认值是YES.
@property (nonatomic, assign) UIActivityIndicatorViewStyle activityIndicatorStyle;
The style that will be used for the UIActivityIndicator (if enabled). Note that this value should bet set beforesetting the imageURL. Setting this value when loading is already in progress will cause the spinner to disappear.
这个显示菊花样式的,不过也需要在执行网络请求之前来设置,如果正在进行网络请求,此时设置了这个值就会导致菊花消失.
@property (nonatomic, assign) NSTimeInterval crossfadeDuration;
The crossfade animation duration, in seconds. If value is greater than 0, the image will crossfade in once it loads instead of appearing suddenly. Defaults to 0.4.
这是个渐隐动画的时间周期,以秒计算.如果这个值大于0,当这张图片已经下载完成之后,这张图片会渐隐出现,默认值是0.4秒.
AsyncImageLoader notifications(通知事宜)
The AsyncImageLoader can generate the following notifications:
AsyncImageLoader能生成以下的集中通知事宜:
AsyncImageLoadDidFinish
This fires when an image has been loaded. The notification object contains the target object that loaded the image file (e.g. the UIImageView) and the userInfo dictionary contains the following keys:
当图片已经加载了,就会激活这个通知.这个通知的对象会包含目标相关的一些信息,如下面的这些键值:
- AsyncImageImageKey
The UIImage that was loaded.
这个加载的UIImage
- AsyncImageURLKey
The NSURL that the image was loaded from.
这个UIImage加载的URL地址
- AsyncImageCacheKey
The NSCache that the image was stored in.
这个UIImage缓存的地方
AsyncImageLoadDidFail
This fires when an image did not load due to an error. The notification object contains the target object that attempted to load the image file (e.g. the UIImageView) and the userInfo dictionary contains the following keys:
如果图片因为一个错误而没有加载出来,这个通知就会包含另外的一些键值对:
- AsyncImageErrorKey
The NSError generated by the underlying URLConnection.
包换NSError信息
- AsyncImageURLKey
The NSURL that the image failed to load from.
这张图片的NSURL地址
AsyncImageLoader properties(加载器属性)
AsyncImageLoader has the following properties:
AsyncImageLoader含有如下的一些属性:
@property (nonatomic, strong) NSCache *cache;
The cache to be used for image load requests. You can change this value at any time and it will affect all subsequent load requests until it is changed again. By default this is set to [AsyncImageLoader sharedCache]
. Set this to nil to disable caching completely, or you can set it to a new NSCache instance or subclass for fine-grained cache control.
图片请求所用的缓存.你可以改变这个属性并瞬间改变所有与之相关的那些子请求.默认值是设置成[AsyncImageLoader sharedCache],将这个值设置成nil会完全关闭缓存.或者你自己设置成另外一个缓存实例来更好的掌握这些缓存.
@property (nonatomic, assign) NSUInteger concurrentLoads;
The number of images to load concurrently. Images are loaded on background threads but loading too many concurrently can choke the CPU. This defaults to 2;
并发加载图片,如果在后台并发加载了太多的图片会噎着CPU的(UI上会卡顿),默认值是2.
@property (nonatomic, assign) NSTimeInterval loadingTimeout;
The loading timeout, in seconds. This defaults to 60, which should be more than enough for loading locally stored images, but may be too short for downloading large images over 3G.
加载的超时时间,以秒计算.默认值是60s,如果用来加载本地图片,60s太长,但是如果通过3G网络来加载,这时间也太短了.
AsyncImageLoader methods(加载器相关方法)
AsyncImageLoader has the following methods:
加载器含有如下的一些方法:
- (void)loadImageWithURL:(NSURL *)URL target:(id)target success:(SEL)success failure:(SEL)failure;
This queues an image for download. If the queue is empty and the image is already in cache, this will trigger the success action immediately.
这个是入队一张图片来下载的.如果这个队列是空的,并且这张图片已经缓存过了,那么就会立即执行完毕.
The target is retained by the AsyncImageLoader, however the loader will monitor to see if the target is being retained by any other objects, and will release it and terminate the file load if it is not. The target can be nil, in which case the load will still happen as normal and can completion can be detected using the AsyncImageLoadDidFinish
and AsyncImageLoadDidFail
notifications.
- (void)loadImageWithURL:(NSURL *)URL target:(id)target action:(SEL)action;
Works the same as above, except the action will only be called if the loading is successful. Failure can still be detected using the AsyncImageLoadDidFail
notification.
功能和上面的一样,只是,当图片成功加载后才会真正的执行那个方法.你也可以用失败的通知来捕捉下载失败.
- (void)loadImageWithURL:(NSURL *)URL;
Works the same as above, but no target or actions are specified.Use AsyncImageLoadDidFinish
and AsyncImageLoadDidFail
to detect when the loading is complete.
和上面的功能一样,只是没有target以及action,使用通知来捕捉吧是否加载完成吧.
- (void)cancelLoadingURL:(NSURL *)URL target:(id)target action:(SEL)action;
This cancels loading the image with the specified URL for the specified target and action.
取消加载指定的URL图片.
- (void)cancelLoadingURL:(NSURL *)URL target:(id)target;
This cancels loading the image with the specified URL for any actions on the specified target;
取消目标上的所有的指定下载URL图片的操作.
- (void)cancelLoadingURL:(NSURL *)URL;
This cancels loading the image with the specified URL.
取消指定加载URL图片地址.
- (void)cancelLoadingImagesForTarget:(id)target action:(SEL)action;
This cancels loading all queued image URLs with the specified action on the specified target;
取消所有这个指定目标的URL图片加载.
- (void)cancelLoadingImagesForTarget:(id)target;
This cancels loading all queued image URLs for the specified target;
取消指定目标的所有的加载图片请求的队列.
- (NSURL *)URLForTarget:(id)target action:(SEL)action;
This returns the most recent image URL set for the given target and action, which may not be the next one to be loaded if several image URLs have been queued on that target.
返回给指定目标最近的几次网络请求加载的URL,但不是按照先后顺序的,因为是并发的嘛.
- (NSURL *)URLForTarget:(id)target;
This returns the most recent image URL set for the given target, which may not be the next one to be loaded if several image URLs have been queued on that target.
同上
Usage(使用)
You can use the AsyncImageView class exactly as you would use a UIImageView. If you want to use it in Interface Builder, drag a regular UImageView or media image into your view as normal, then change its class to AsyncImageView in the inspector.
你可以像使用UIImageView那样来使用AsyncImageView,如果你想在IB里面使用,你直接拖拽UImageView到你的空间中,然后替换掉类名即可.
For cases where you cannot use an AsyncImageView, such as the embedded imageView of a UIButton or UITableView, the UIImageView category means that you can still set the imageURL property on the imageView to load the image in the background. You will not get the advanced features of the AsyncImageView class this way however (such as the loading spinner), unless you re-implement them yourself.
某些情况下你无法使用AsyncImageView,例如植入到UIButton或者UITableView上的图片,但是,UIImageView类目还是可以帮助你在后台设置imageURL属性的.在这种情形下,你就不能使用AsyncImageView的对象了,除非你自己去重新实现他们.
To load or download an image, simply set the imageURL property to the URL of the desired image. This can be a remote URL or a local fileURL that points to the application's bundle or documents folder.
加载一张图片或者系统内的图片,简单的设置imageURL,他可以加载本地的或者网络上的图片.
If you want to display a placeholder image in the meantime, just manually set the image property of the UIImageView to your placeholder image and it will be overwritten once the image specified by the URL has loaded.
如果你想在加载图片的时候显示一张placeholder图片,请手动设置你的UIImageView属性到这张图片上,当网络请求完成后,会自动替换的.
If you want to asynchronously load a smaller thumbnail image while the main image loads, just set the thumbnail URL first, then the full image URL. AsyncImageLoader will ensure that the images are loaded in the correct order. If the larger image is already cached, or loads first for some reason, the thumbnail image loading will be cancelled.
如果你想同时加载同一张图片的小图和大图,先设置 thumbnail URL地址,再设置大图的 URL地址.AsyncImageLoader会确保准确的加载顺序,如果大图之前缓存过了,那么会取消加载小图的.
To detect when the image has finished loading, you can use NSNotificationCenter in conjunction with the AsyncImageLoadDidFinish
notification, or you can use KVO (Key-Value Observation) to set up an observer on the UIImageView's image property. When the image has finished loading, the image will be set, and with KVO you can detect this and react accordingly.
为了监测图片是否加载完毕,你可以使用NSNotificationCenter来获取加载的通知,或者你通过KVO来设置监听者来监听这些,当图片加载完成后,就会被设置上,KVO就会直接监听到这个举动.
By default, all loaded images are cached, and if the app loads a large number of images, the cache will keep building up until a memory warning is triggered. You can avoid memory warnings by manually removing items from the cache according to your own maintenance logic. You can also disable caching either universally or for specific images by setting the shared AsyncImageLoader's cache property to nil
before loading an image (set it back to [AsyncImageLoader sharedInstance]
to re-enable caching afterwards).
默认情况下,所有图片都是缓存起来的,如果app加载了很多大的图片,那么缓存就会越来越大知道出现内存警告.你可以根据逻辑来删除那些你不要的那些图片,你也可以不用缓存图片每回直接从网络请求也是可行的.
心得:
1. 该AsyncImageView不是基于GCD的,所以使用在UITableView或者UIButton中会出现一些使用上的限制
2. 可以加载图片序列,先加载小图再加载大图
3. 加载图片的时候可以显示出菊花
4. 图片成功加载后会有着渐隐出现的效果
5. 图片是否加载成功通过通知中心来实现
6. 比不上SDWebImage,但也有自己的亮点,还是挺好用的.