Objective-cマルチスレッド操作カスタムNSOperationシミュレーションダウンロード
11889 ワード
前に書いて人を降ろして...コンテンツが再びロックされないように...全てがここにある
前に書く
マルチスレッドを使用して画像をダウンロードし、メモリキャッシュとディスクキャッシュを使用します.ここではNSOperationとその派生クラスを理解するためにアプリに適用するには、成熟したサードパーティライブラリをダウンロードしてください.
効果
効果
複数のピクチャをダウンロードするときにスレッドの同時数を制御できます
ぶんせきカスタムNSOperation実行ダウンロード操作 は1つのキュー操作をカプセル化し、N個のスレッドを作成し、キュー制御は を併発する.スレッドtagにより対応ピクチャ を検索するキューtagにより対応するキュー を検索する.キャッシュメモリとディスクキャッシュ を設定する.ダウンロード完了delegateまたはblockによるコールバック通知 コード#コード#汎用コンテンツスレッド完了時のコールバック、ピクチャロード時のコールバック カスタムNSOperationダウンロードデータ ロードピクチャ:キャッシュロードとスレッドキューロード 外部呼び出しおよびテスト
DEMOアドレス
https://github.com/gongxiaokai/DownloadImageDemo
前に書く
マルチスレッドを使用して画像をダウンロードし、メモリキャッシュとディスクキャッシュを使用します.ここではNSOperationとその派生クラスを理解するためにアプリに適用するには、成熟したサードパーティライブラリをダウンロードしてください.
効果
効果
複数のピクチャをダウンロードするときにスレッドの同時数を制御できます
ぶんせき
#ifndef Uinty_h
#define Uinty_h
#import
typedef void(^DownloadImageDataBlock)(NSData *data,int tag);
typedef void(^DownloadImageBlock)(UIImage *image,int tag,int queueTag);
static int const kImageViewTag = 1990;
//
@protocol DownloadOperationDelegate
//
- (void)downloadOperationWithData:(NSData*)data withTag:(int)tag;
@end
//
@protocol DownloadImageDelegate
//
- (void)downloadImageFinishedWith:(UIImage*)image andTag:(int)tag withQueueTag:(int)queueTag;
@end
#endif /* Uinty_h */
#import
#import "Uinty.h"
@interface DownloadOperation : NSOperation
//block
@property (nonatomic,copy)DownloadImageDataBlock imageDataBlock;
//
@property (nonatomic,assign)int tag;
//
@property (nonatomic,strong)id delegate;
//
- (instancetype)initWithUrlStr:(NSString*)urlStr;
+ (instancetype)downloadOperationWithUrlStr:(NSString*)urlStr;
@end
#import "DownloadOperation.h"
@interface DownloadOperation()
@property(nonatomic,copy)NSString *urlStr;
@end
@implementation DownloadOperation
- (instancetype)initWithUrlStr:(NSString*)urlStr {
self = [super init];
if (self) {
self.urlStr = urlStr;
}
return self;
}
+ (instancetype)downloadOperationWithUrlStr:(NSString*)urlStr {
return [[DownloadOperation alloc] initWithUrlStr:urlStr];
}
-(void)main {
NSURL *url = [NSURL URLWithString:self.urlStr];
NSData *data = [NSData dataWithContentsOfURL:url];
//
sleep(1);
//
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
//block
if (self.imageDataBlock) {
self.imageDataBlock(data,self.tag);
}
//
if ([self.delegate respondsToSelector:@selector(downloadOperationWithData:withTag:)]) {
[self.delegate downloadOperationWithData:data withTag:self.tag];
}
}];
}
@end
#import
#import "DownloadOperation.h"
@interface DownloadImage : NSObject
//
@property (nonatomic,copy)DownloadImageBlock downloadFinishedBlock;
//
@property (nonatomic,copy)NSString *urlStr;
//
@property (nonatomic,strong)NSArray *urlArray;
//
@property (nonatomic,assign)int maxOperationCount;
//
@property (nonatomic,strong)id delegate;
//
@property (nonatomic,assign)int tag;
// :M
@property (nonatomic,assign)NSUInteger diskCapacity;
@property (nonatomic,assign)NSUInteger MemoryCapacity;
// url
- (instancetype)initWithUrlStrArray:(NSArray*)urlArray withStartTag:(int)startTag ;
// url
- (instancetype)initWithUrlStr:(NSString*)urlStr ;
//
+ (instancetype)downloadImageWithUrlStrArray:(NSArray*)urlArray withStartTag:(int)startTag ;
+ (instancetype)downloadImageWithUrlStr:(NSString*)urlStr ;
//
- (void)starDownloadImage;
@end
//
// DownloadImage.m
// DownloadImageDemo
//
// Created by gongwenkai on 2017/1/3.
// Copyright © 2017 gongwenkai. All rights reserved.
//
#import "DownloadImage.h"
#import "DownloadOperation.h"
@interface DownloadImage()
@property (nonatomic,strong)NSOperationQueue *queue;
@property (nonatomic,strong)NSCache *imageCache;
@property (nonatomic,copy)NSString *cachePath;
@property (nonatomic,assign)int imageStartTag;
@end
@implementation DownloadImage
#pragma mark -
- (NSString *)cachePath {
if (!_cachePath) {
_cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
}
return _cachePath;
}
- (NSCache *)imageCache {
if (!_imageCache) {
_imageCache = [[NSCache alloc] init];
_imageCache.countLimit = 100;
}
return _imageCache;
}
- (NSOperationQueue *)queue {
if (!_queue) {
_queue = [[NSOperationQueue alloc] init];
}
return _queue;
}
- (NSUInteger)MemoryCapacity {
if (!_MemoryCapacity) {
_MemoryCapacity = 1;
}
return _MemoryCapacity;
}
- (NSUInteger)diskCapacity {
if (!_diskCapacity) {
_diskCapacity = 10;
}
return _diskCapacity;
}
- (int)maxOperationCount {
if (!_maxOperationCount) {
_maxOperationCount = 2;
}
return _maxOperationCount;
}
#pragma mark -
+ (instancetype)downloadImageWithUrlStrArray:(NSArray*)urlArray withStartTag:(int)startTag {
return [[DownloadImage alloc] initWithUrlStrArray:urlArray withStartTag:startTag];
}
+ (instancetype)downloadImageWithUrlStr:(NSString*)urlStr {
return [[DownloadImage alloc] initWithUrlStr:urlStr];
}
- (instancetype)initWithUrlStrArray:(NSArray*)urlArray withStartTag:(int)startTag{
self = [super init];
if (self) {
self.urlArray = urlArray;
self.imageStartTag = startTag;
}
return self;
}
- (instancetype)initWithUrlStr:(NSString*)urlStr {
self = [super init];
if (self) {
self.urlStr = urlStr;
}
return self;
}
// set url
- (void)setUrlStr:(NSString *)urlStr {
_urlStr = urlStr;
_urlArray = [NSArray arrayWithObject:urlStr];
}
#pragma mark -
- (void)starDownloadImage {
//
NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:self.MemoryCapacity * 1024 * 1024 diskCapacity:self.diskCapacity * 1024 * 1024 diskPath:nil];
[NSURLCache setSharedURLCache:URLCache];
//
for (int i = 0; i < self.urlArray.count; i++) {
int imageTag = self.imageStartTag + i;
NSString *urlStr = self.urlArray[i];
//
UIImage *memoryImage = [self.imageCache objectForKey:urlStr];
if (memoryImage) {
//block
if (self.downloadFinishedBlock) {
self.downloadFinishedBlock(memoryImage,imageTag,self.tag);
}
//
if ([self.delegate respondsToSelector:@selector(downloadImageFinishedWith:andTag:withQueueTag:)]) {
[self.delegate downloadImageFinishedWith:memoryImage andTag:imageTag withQueueTag:self.tag];
}
continue;
}
//
NSString *imagePath=[urlStr lastPathComponent];
NSString *imageCachePath = [self.cachePath stringByAppendingPathComponent:imagePath];
NSData *data = [NSData dataWithContentsOfFile:imageCachePath];
if (data) {
UIImage *diskImage = [UIImage imageWithData:data];
//block
if (self.downloadFinishedBlock) {
self.downloadFinishedBlock(diskImage,imageTag,self.tag);
}
//
if ([self.delegate respondsToSelector:@selector(downloadImageFinishedWith:andTag:withQueueTag:)]) {
[self.delegate downloadImageFinishedWith:diskImage andTag:imageTag withQueueTag:self.tag];
}
continue;
}
//
self.queue.maxConcurrentOperationCount = self.maxOperationCount;
DownloadOperation *op = [DownloadOperation downloadOperationWithUrlStr:urlStr];
op.tag = i + kImageViewTag;
if (self.urlArray.count < self.maxOperationCount) {
[op start];
}else {
[self.queue addOperation:op];
}
//
op.imageDataBlock = ^(NSData *data,int tag){
UIImage *image = [UIImage imageWithData:data];
//
[self.imageCache setObject:image forKey:urlStr];
//
[data writeToFile:imageCachePath atomically:YES];
//block
if (self.downloadFinishedBlock) {
NSLog(@"tage ======%d",tag);
self.downloadFinishedBlock(image,tag,self.tag);
}
//
if ([self.delegate respondsToSelector:@selector(downloadImageFinishedWith:andTag:withQueueTag:)]) {
[self.delegate downloadImageFinishedWith:image andTag:tag withQueueTag:self.tag];
}
};
}
}
@end
- (void)viewDidLoad {
[super viewDidLoad];
for (int i = 0; i < 6; i++) {
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, i*105, 100, 100)];
imgView.tag = i + kImageViewTag;
imgView.backgroundColor = [UIColor redColor];
[self.view addSubview:imgView];
}
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(120, 100, 100, 100)];
imgView.backgroundColor = [UIColor redColor];
imgView.tag = 1234;
[self.view addSubview:imgView];
NSLog(@"%@",NSHomeDirectory());
}
- (IBAction)clickLoadImages:(id)sender {
//
DownloadImage *download = [DownloadImage downloadImageWithUrlStrArray:@[@"http://img.hb.aicdn.com/6e004cb3c5f58f016a57b90f8bbb93d7075453f2efd0-anTckt_fw658",@"http://img.hb.aicdn.com/fb18b522caf2821adb7af96f8656787f8d9bdad31bdec-6f6h4X_fw658",@"http://img.hb.aicdn.com/22e4dfd8d135de7ae0d451e351c00bddf732919920840-BMRw4Z_fw658",@"http://img.hb.aicdn.com/536c96af48b38faca5bcad20ba0ea6aba8929b711e5b4-lvdBlI_fw658",@"http://img.hb.aicdn.com/055e5458bd340a52ca0067f5d7c22b6c3b18d119292ae-QLEsYp_fw658",@"http://img.hb.aicdn.com/b50481ab8a2b4e3587068df0552ebad08409f0b3ca23-8gBQ9x_fw658"] withStartTag:kImageViewTag];
//
download.maxOperationCount = 3;
download.tag = 0;
download.delegate = self;
/* block
download.downloadFinishedBlock = ^(UIImage *image,int tag,int queueTag) {
UIImageView *img = [self.view viewWithTag:tag];
img.image = image;
NSLog(@"jicia====%d",tag);
};
*/
//
[download starDownloadImage];
}
- (IBAction)clickLoadSingalImage:(id)sender {
//
DownloadImage *down = [DownloadImage downloadImageWithUrlStr:@"http://img.hb.aicdn.com/b50481ab8a2b4e3587068df0552ebad08409f0b3ca23-8gBQ9x_fw658"];
down.tag = 1;
down.delegate = self;
/* block
down.downloadFinishedBlock = ^(UIImage *image,int tag,int queueTag) {
UIImageView *imgV = [self.view viewWithTag:1234];
imgV.image = image;
};
*/
[down starDownloadImage];
}
- (IBAction)cleanAll:(id)sender {
for (int i = 0; i < 6; i++) {
UIImageView *imgView = [self.view viewWithTag:i + kImageViewTag];
imgView.image = nil;
}
UIImageView *imgView = [self.view viewWithTag:1234];
imgView.image = nil;
}
//
- (void)downloadImageFinishedWith:(UIImage*)image andTag:(int)tag withQueueTag:(int)queueTag{
if (queueTag == 0) {
UIImageView *img = [self.view viewWithTag:tag];
img.image = image;
} else if (queueTag == 1) {
UIImageView *imgV = [self.view viewWithTag:1234];
imgV.image = image;
}
}
DEMOアドレス
https://github.com/gongxiaokai/DownloadImageDemo