@通常,我们常常习惯于用第三方的库,来实现很多功能需求,方便简洁快速,但是,为了进一步的提升自己,我们可以尝试去了解它内部的实现机制,所有的功能实现,万变不离其宗
@下面代码示例,都是很基础的知识,来实现这一功能
~~~
#import <Foundation/Foundation.h>
@interface ImageDownloader : NSObject
@property (nonatomic,copy) NSString * imageUrl;
//开始下载图像
- (void)startDownloadImage:(NSString *)imageUrl;
//从本地加载图像
- (UIImage *)loadLocalImage:(NSString *)imageUrl;
@end
#import "ImageDownloader.h"
@implementation ImageDownloader
- (void)dealloc
{
self.imageUrl = nil;
Block_release(_completionHandler);
[super dealloc];
}
#pragma mark - 异步加载
- (void)startDownloadImage:(NSString *)imageUrl
{
self.imageUrl = imageUrl;
// 先判断本地沙盒是否已经存在图像,存在直接获取,不存在再下载,下载后保存
// 存在沙盒的Caches的子文件夹DownloadImages中
UIImage * image = [self loadLocalImage:imageUrl];
if (image == nil) {
// 沙盒中没有,下载
// 异步下载,分配在程序进程缺省产生的并发队列
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 多线程中下载图像--->方便简洁写法
NSData * imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]];
// 缓存图片
[imageData writeToFile:[self imageFilePath:imageUrl] atomically:YES];
// 回到主线程完成UI设置
dispatch_async(dispatch_get_main_queue(), ^{
UIImage * image = [UIImage imageWithData:imageData];
/**
* ............ 进行UI设置
* ............ imageView.image = image;
* 也可以利用blcok,将image对象传到别处去
*/
});
});
}
}
#pragma mark - 加载本地图像
- (UIImage *)loadLocalImage:(NSString *)imageUrl
{
self.imageUrl = imageUrl;
// 获取图像路径
NSString * filePath = [self imageFilePath:self.imageUrl];
UIImage * image = [UIImage imageWithContentsOfFile:filePath];
if (image != nil) {
return image;
}
return nil;
}
#pragma mark - 获取图像路径
- (NSString *)imageFilePath:(NSString *)imageUrl
{
// 获取caches文件夹路径
NSString * cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSLog(@"caches = %@",cachesPath);
// 创建DownloadImages文件夹
NSString * downloadImagesPath = [cachesPath stringByAppendingPathComponent:@"DownloadImages"];
NSFileManager * fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:downloadImagesPath]) {
[fileManager createDirectoryAtPath:downloadImagesPath withIntermediateDirectories:YES attributes:nil error:nil];
}
#pragma mark 拼接图像文件在沙盒中的路径,因为图像URL有"/",要在存入前替换掉,随意用"_"代替
NSString * imageName = [imageUrl stringByReplacingOccurrencesOfString:@"/" withString:@"_"];
NSString * imageFilePath = [downloadImagesPath stringByAppendingPathComponent:imageName];
return imageFilePath;
}
@end
~~~
- 前言
- 沙盒机制与文件(一)
- 沙盒机制和文件(二)
- 沙盒机制和文件(三)
- NSBundle介绍以及读取沙盒文件路径问题
- 数据持久化(一)-----归档 读写 文件路径
- 数据持久化(二)-----Sqlite
- 数据持久化(三)使用第三方类库FMDB
- 数据持久化(四)之NSUserDefaults
- 数据持久化(五)之CoreData
- 数据持久化(六)之Using CoreData with MagicalRecord
- 数据解析(一)解析XML之系统自带NSXMLParse类
- 数据解析(二)解析XML之GDataXMLNode
- 数据解析(三)解析JSON-----系统自带NSJSONSerialization 与 第三方JSONKit
- iOS多线程编程(一)NSThread
- iOS多线程编程(二)NSOperationQueue
- iOS多线程编程(三)Grand Central Dispatch(GCD)详解
- iOS网络编程(一)NSURLConnection
- iOS网络编程(二) 自定义请求网络类----推荐用于需要请求过程片段数据
- iOS网络编程(三) 异步加载及缓存图片---->SDWebImage
- iOS网络编程(四) 异步加载及缓存图片-----自定义类
- iOS网络编程(五) 异步加载及缓存图片-----EGO
- iOS网络编程(六) NSURLSession详解
- iOS网络编程(7) 第三方开源库----->AFNetworking