多任务多线程下载图片

分了三个任务下载每张图片,同时写入文件

viewController.m

 1 #import "ViewController.h"
 2 #import "DownLoadManager.h"
 3 #import "PictureCell.h"
 4 
 5 @interface ViewController ()<UITableViewDataSource,UITableViewDelegate>
 6 @property (weak, nonatomic) IBOutlet UITableView *showTableView;
 7 @property (nonatomic,strong) DownLoadManager * downloader;
 8 @end
 9 
10 @implementation ViewController
11 
12 - (void)viewDidLoad {
13     [super viewDidLoad];
14     
15     self.downloader = [DownLoadManager sharedManager];
16     _downloader.urlsArray = @[@"http://imgsrc.baidu.com/forum/w%3D580/sign=c390a2a4ccbf6c81f7372ce08c3fb1d7/d53f8794a4c27d1e8d097d081bd5ad6edcc438ca.jpg",@"http://img1.3lian.com/2015/a1/124/d/181.jpg",@"http://img1.3lian.com/2015/w7/87/d/9.jpg"];
17     __weak ViewController * weakself = self;
18     _downloader.pblock =^(CGFloat AddProgress,NSInteger index){
19         dispatch_sync(dispatch_get_main_queue(), ^{
20             PictureCell * cell = [weakself.showTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:index  inSection:0]];
21             cell.pro=AddProgress;
22         });
23     };
24     [_downloader start];
25 }
26 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
27     return 1;
28 }
29 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
30     return _downloader.urlsArray.count;
31 }
32 -(PictureCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath{
33     PictureCell * cell = [tableView dequeueReusableCellWithIdentifier:@"cellID"];
34     cell.name = [[self.downloader.urlsArray objectAtIndex:indexPath.row]lastPathComponent];
35     NSLog(@"%@",cell.name);
36     return cell;
37 }
38 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
39     return 80;
40 }

DownLoadManager.m

#import "DownLoadManager.h"
#import "DownLoadTask.h"
@interface DownLoadManager ()<NSURLSessionDataDelegate,NSURLSessionDelegate,NSURLSessionTaskDelegate>

@end

@implementation DownLoadManager
+(instancetype)sharedManager{
    static DownLoadManager * instance = nil;
    dispatch_once_t token;
    dispatch_once(&token, ^{
        instance = [[DownLoadManager alloc]init];
    });
    return instance;
}
-(void)start{
    for (int i = 0; i<_urlsArray.count; i++) {
        NSString * urlString = [_urlsArray objectAtIndex:i];
        NSURL * url = [NSURL URLWithString:urlString];
        NSURLSessionConfiguration * config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
        NSURLSession * session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
        NSURLSessionDataTask * dataTask = [session dataTaskWithURL:url];
        [dataTask resume];
    }
}
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{
    NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *)response;
    if(httpResponse.statusCode>=400){
        NSLog(@"请求错误");
    }else{
        completionHandler(NSURLSessionResponseCancel);
        long long totalLength = httpResponse.expectedContentLength;
        if (totalLength != -1) {
            NSString * name = [[httpResponse.URL relativeString]lastPathComponent];
            [self creatFileWithName:name];
            long long average = totalLength/3;
            long long location = 0;
            long long length = average;
            for (int i = 0; i<3; i++) {
                if (i == 2) {
                    length = totalLength-location;
                }
                [[[DownLoadTask alloc]init] DownLoadWithURL:httpResponse.URL location:location length:length progressBlock:^(CGFloat datalength) {
                    self.pblock(1.0*datalength/totalLength,i);
                }];
                location =location + length + 1;
            }
        }
    }
}
-(void)creatFileWithName:(NSString *)name{
    NSString * docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSString * filePath = [docPath stringByAppendingPathComponent:name];
    [[NSFileManager defaultManager]createFileAtPath:filePath contents:nil attributes:nil];
}

DownLoadTask.m

#import "DownLoadTask.h"
@interface DownLoadTask()<NSURLSessionDataDelegate,NSURLSessionDataDelegate,NSURLSessionTaskDelegate>
@property (strong ,nonatomic) NSURL * url;
@property (assign ,nonatomic) long long location;
@property (assign ,nonatomic) long long length;
@property (strong ,nonatomic) NSFileHandle * filehandle;
@property (strong ,nonatomic) NSCondition * condition;//线程加锁解锁

@property (copy,nonatomic) ProgressDataBlock problock;
@end

@implementation DownLoadTask
-(void)DownLoadWithURL:(NSURL *)url location:(long long)locationPoint length:(long long)len progressBlock:(ProgressDataBlock)pblock{
    self.problock = pblock;
    self.url = url;
    self.location = locationPoint;
    self.length = len;
    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url];
    NSString * range = [NSString stringWithFormat:@"bytes=%lld-%lld",_location,_location+_length];
    [request setValue:range forHTTPHeaderField:@"Range"];
    NSURLSessionConfiguration * config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
    NSURLSession * session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[[NSOperationQueue alloc]init]];
    NSURLSessionDataTask * datatask = [session dataTaskWithRequest:request];
    [datatask resume];
}
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{
    if (response.expectedContentLength!=-1) {
        NSString * filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:[_url lastPathComponent]];
        
        self.filehandle = [NSFileHandle fileHandleForWritingAtPath:filePath];
        [_filehandle seekToFileOffset:_location];
        self.condition = [[NSCondition alloc]init];
        
        completionHandler(NSURLSessionResponseAllow);
    }
}
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{
    [_condition lock];
    [_filehandle writeData:data];
    self.problock(data.length);
    [_condition unlock];
}
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
    [_filehandle closeFile];
}
@end

PictureCell.m

#import "PictureCell.h"
@interface PictureCell()
@property (weak, nonatomic) IBOutlet UIImageView *image;
@property (weak, nonatomic) IBOutlet UIProgressView *progressView;
@end
@implementation PictureCell

- (void)awakeFromNib {
    // Initialization code
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
}
-(void)setPro:(CGFloat)pro{
    _pro = pro;
    
    self.progressView.progress += pro;
    NSLog(@"%f",self.progressView.progress);
    if (self.progressView.progress > 0.999) {
        NSString * docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
        NSString * filePath = [docPath stringByAppendingPathComponent:self.name];
        
        NSData * data = [NSData dataWithContentsOfFile:filePath];
        UIImage * image = [UIImage imageWithData:data];
        self.image.image = image;
    }
}
@end

 

posted @ 2016-03-21 19:32  浪味小仙女  阅读(502)  评论(0编辑  收藏  举报