AFN 3.0学习总结(十)
参考:AFNetworking 3.0 源码解读(十)之 UIActivityIndicatorView/UIRefreshControl/UIImageView + AFNetworking
说明:很多内容都是摘抄原文,只是根据自己的需要进行摘抄或者总结,如有不妥请及时指出,谢谢。
我们应该看到过很多类似这样的例子:某个控件拥有加载网络图片的能力。但这究竟是怎么做到的呢?看完这篇文章就明白了。
这篇我们会介绍 AFNetworking 中的3个UIKit中的分类。UIActivityIndicatorView UIRefreshControl UIImageView。读完本篇就能够明白控件是如何显示网络图片的。那么如果你有兴趣,可以尝试让一个控件的layer也能够加载网络图片。
1、UIActivityIndicatorView+AFNetworking UIActivityIndicatorView的这个分类最简单,它只提供了一个方法:setAnimatingWithStateOfTask: 只要给UIActivityIndicatorView一个 task UIActivityIndicatorView会根据数据的加载情况 自动 开始动画或者结束动画。
2、UIRefreshControl+AFNetworking UIRefreshControl的这个分类的使用跟上边的UIActivityIndicatorView+AFNetworking一模一样。
3、UIImageView+AFNetworking UIImageView是最常用的显示图片的控件。额外增加了 placeholderImage(替代图片) 这个属性和 success failure 这两个block来自定义一些事件。最后增加了两个取消某个状态下的图片下载的方法。我们看下边的图片就好了:
image
image
UIImageView+AFNetworking
objc_setAssociatedObject
这里出现了很多调用objc_setAssociatedObject的地方,简单解释一下:
objc_setAssociatedObject方法中第二个参数是一个地址,因此我们可以用@selector或者自定义一个全局的const字段,取它的地址,如:
定义了这么一个属性
@property (readwrite, nonatomic, strong)NSString *abc;
实现如下:
- (NSString *)abc {
return objc_getAssociatedObject(self, &abcde);
}
使用如下,和普通的没有太大区别:
UIImageView *imageView = [[UIImageView alloc] init];
[imageView setValue:@"qwer" forKey:@"abc"];
NSString *str = [imageView valueForKey:@"abc"];
NSLog(@"%@",str);
核心方法
- (void)setImageWithURLRequest:(NSURLRequest *)urlRequest
placeholderImage:(UIImage *)placeholderImage
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success
failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure
对该方法的逻辑,描述如下:
1、我们规定,使用这个分类每加载一次图片就生成一个af_activeImageDownloadReceipt,这个凭据一旦下载完成后,就要设置为nil
2、首先判断urlRequest是否有效,有效继续往下走,无效的话取消之前的下载,并用赋值替代图片。说明,如果urlRequest无效,之前的下载也会被取消掉
3、判断当前添加的下载任务,和正在进行的下载是不是一样的,如果一样,则取消这个添加的任务
4、不一样的话,就取消之前的下载任务
5、在缓存中取图片,取到了直接返回成功,否则先用替代图片显示,并开始下载