@通常,我們常常習慣于用第三方的庫,來實現很多功能需求,方便簡潔快速,但是,為了進一步的提升自己,我們可以嘗試去了解它內部的實現機制,所有的功能實現,萬變不離其宗
@下面代碼示例,都是很基礎的知識,來實現這一功能
~~~
#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