用NSOperation写下载队列

来源:互联网 发布:mac系统彻底删除软件 编辑:程序博客网 时间:2024/06/08 02:26

用NSOperation写下载队列

 

说明

1. 支持缓存机制

2. 图片都是在主线程中加载

3. 文件名用了md5加密

*这东西被人写烂了,但大伙如果对NSOperation不熟悉的话,可以看看本人的实现.

 

源码

https://github.com/YouXianMing/NSOperationExample

复制代码
////  ImageDownloadOperation.h//  NSOperationDownloadImage////  Created by YouXianMing on 15/9/7.//  Copyright (c) 2015年 YouXianMing. All rights reserved.//#import <Foundation/Foundation.h>@class ImageDownloadOperation;@protocol ImageDownloadOperationDelegate <NSObject>@required- (void)imageDownloadOperation:(ImageDownloadOperation *)operation data:(NSData *)data;@end@interface ImageDownloadOperation : NSOperation {        BOOL  _executing;    BOOL  _finished;}/** *  代理 */@property (nonatomic, weak)   id <ImageDownloadOperationDelegate> delegate;/** *  图片地址 */@property (nonatomic, strong) NSString *imageUrlString;/** *  便利构造器 * *  @param urlString 图片地址 *  @param delegate  代理 * *  @return 实例对象 */+ (instancetype)operationWithImageUrlString:(NSString *)urlString                                   delegate:(id <ImageDownloadOperationDelegate>)delegate;@end
复制代码
复制代码
////  ImageDownloadOperation.m//  NSOperationDownloadImage////  Created by YouXianMing on 15/9/7.//  Copyright (c) 2015年 YouXianMing. All rights reserved.//#import "ImageDownloadOperation.h"#import <CommonCrypto/CommonDigest.h>@interface ImageDownloadOperation ()@property (nonatomic, strong) NSURLConnection *connection;@property (nonatomic, strong) NSString        *md5String;@property (nonatomic, strong) NSString        *filePathString;@end@implementation ImageDownloadOperation- (void)main {        // 验证图片地址是否为空    if (_imageUrlString.length <= 0) {                [self delegateEventWithData:nil];        [self completeOperation];                return;    }        // 生成文件路径    self.md5String      = [self MD5HashWithString:_imageUrlString];    self.filePathString = [self pathWithFileName:self.md5String];        // 文件如果存在则直接读取    BOOL exist = [[NSFileManager defaultManager] fileExistsAtPath:self.filePathString isDirectory:nil];    if (exist) {                [self delegateEventWithData:[NSData dataWithContentsOfFile:self.filePathString]];        [self completeOperation];                return;    }        NSURL        *url     = [NSURL URLWithString:_imageUrlString];    NSURLRequest *request = [NSURLRequest requestWithURL:url];    self.connection       = [NSURLConnection connectionWithRequest:request delegate:self];        // 让线程不结束    do {                @autoreleasepool {                        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];                        if (self.isCancelled) {                                [self completeOperation];            }        }            } while (self.isExecuting && self.isFinished == NO);}#pragma mark - 网络代理- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {}- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {        [self writeData:data toPath:self.filePathString];    [self delegateEventWithData:data];}- (void)connectionDidFinishLoading:(NSURLConnection *)connection {        [self completeOperation];}- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {        [self delegateEventWithData:nil];    [self completeOperation];}#pragma mark - + (instancetype)operationWithImageUrlString:(NSString *)urlString                                   delegate:(id <ImageDownloadOperationDelegate>)delegate {    ImageDownloadOperation *operation = [[ImageDownloadOperation alloc] init];    operation.delegate                = delegate;    operation.imageUrlString          = urlString;        return operation;}#pragma mark -- (void)completeOperation {        [self willChangeValueForKey:@"isFinished"];    [self willChangeValueForKey:@"isExecuting"];    _executing = NO;    _finished  = YES;    [self didChangeValueForKey:@"isExecuting"];    [self didChangeValueForKey:@"isFinished"];}- (void)start {        if ([self isCancelled]) {                [self willChangeValueForKey:@"isFinished"];        _finished = YES;        [self didChangeValueForKey:@"isFinished"];                return;    }        [self willChangeValueForKey:@"isExecuting"];    [NSThread detachNewThreadSelector:@selector(main) toTarget:self withObject:nil];    _executing = YES;    [self didChangeValueForKey:@"isExecuting"];}- (BOOL)isExecuting {        return _executing;}- (BOOL)isFinished {        return _finished;}- (BOOL)isConcurrent {        return YES;}#pragma mark -- (NSString *)MD5HashWithString:(NSString *)string {        CC_MD5_CTX md5;        CC_MD5_Init(&md5);    CC_MD5_Update(&md5, [string UTF8String], (CC_LONG) [string length]);        unsigned char digest[CC_MD5_DIGEST_LENGTH];    CC_MD5_Final(digest, &md5);        NSString *s = [NSString stringWithFormat: @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",                   digest[0],  digest[1],                   digest[2],  digest[3],                   digest[4],  digest[5],                   digest[6],  digest[7],                   digest[8],  digest[9],                   digest[10], digest[11],                   digest[12], digest[13],                   digest[14], digest[15]];        return s;}- (NSString *)pathWithFileName:(NSString *)name {    NSString *path = [NSString stringWithFormat:@"/Documents/%@", name];    return [NSHomeDirectory() stringByAppendingPathComponent:path];}- (void)delegateEventWithData:(NSData *)data {        if (_delegate && [_delegate respondsToSelector:@selector(imageDownloadOperation:data:)]) {                dispatch_async(dispatch_get_main_queue(), ^{                        [_delegate imageDownloadOperation:self data:data];        });    }}- (void)writeData:(NSData *)data toPath:(NSString *)path {    dispatch_async(dispatch_get_global_queue(0, 0), ^{                [data writeToFile:path atomically:YES];    });}@end
复制代码

 

细节

1 0
原创粉丝点击