当前位置: 代码迷 >> Iphone >> iPhone开发多线程开发之NSOperation&NSOperationQueue——异步上载图片
  详细解决方案

iPhone开发多线程开发之NSOperation&NSOperationQueue——异步上载图片

热度:8707   发布时间:2013-02-26 00:00:00.0
iPhone开发多线程开发之NSOperation&NSOperationQueue——异步下载图片 .
实现的功能:1)演示多线程NSOperation&NSOperationQueue开发;2)子线程中执行下载图片工作,图片下载完成前显示等待框和下载进度条;

关键词:多线程 NSOperation NSOperationQueue 等待框


效果图如下:
[img]

[/img]

[img]

[/img]





1、新建视图控制器ViewController(不带xib),作为根视图控制器,通过ViewController的-(void)loadView方法构建UI。




2、新建继承自NSOperation且实现协议NSURLConnectionDelegate的类DownLoadImageTask,DownLoadImageTask.h如下:
#import <Foundation/Foundation.h>@protocol DownLoadImageDelegate;@interface DownLoadImageTask : NSOperation<NSURLConnectionDelegate>{    int operationId;    long long totalLength;    BOOL done;}@property int operationId;@property(nonatomic,assign) id<DownLoadImageDelegate>downloadImageDelegate;@property(nonatomic,retain) NSMutableData *buffer;@property(nonatomic,retain) NSURLRequest *request;@property(nonatomic,retain) NSURLConnection *connection;- (id)initWithURLString:(NSString *)url;@end@protocol DownLoadImageDelegate//图片下载完成的委托-(void)imageDownLoadFinished:(UIImage *)img;//更新图片下载进度条的值-(void)updateDownProgress:(double) value;@end



DownLoadImageTask.m如下:
@implementation DownLoadImageTask@synthesize operationId;@synthesize downloadImageDelegate;@synthesize buffer;@synthesize request;@synthesize connection;- (id)initWithURLString:(NSString *)url{    NSLog(@"url=%@",url);    self = [super init];    if(self){        request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];        buffer = [NSMutableData data];    }    return self;}//主要处理方法-(void)start{ //或者main    NSLog(@"DownLoadImageTask-start");        if(![self isCancelled]){        //暂停一下        [NSThread sleepForTimeInterval:1];        //设置connection及其代理        connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];        if(connection!=nil){            while(!done){                [[NSRunLoop currentRunLoop]runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];            }        }    }}-(void)httpConnectEndWithError{    //[self hiddenWaiting];    NSLog(@"httpConnectEndWithError");}-(void)dealloc{    buffer = nil;    connection = nil;    request = nil;    downloadImageDelegate = nil;}#pragma NSURLConnection delegate methods//不执行缓存-(NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse{    return nil;}//连接发生错误-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{    [self performSelectorOnMainThread:@selector(httpConnectEndWithError) withObject:self waitUntilDone:NO];    [buffer setLength:0];}//收到响应- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;    if(httpResponse && [httpResponse respondsToSelector:@selector(allHeaderFields)]){        NSDictionary *httpResponseHeaderFields = [httpResponse allHeaderFields];        totalLength = [[httpResponseHeaderFields objectForKey:@"Content-Length"] longLongValue];        NSLog(@"totalLength is %lld",totalLength);    }}//接收数据-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{    //NSLog(@"didReceiveData...");    [buffer appendData:data];        double progressValue = totalLength==0?0:((double)([buffer length])/(double)totalLength);    //更新进度条值    [downloadImageDelegate updateDownProgress:progressValue];}//下载完毕-(void)connectionDidFinishLoading:(NSURLConnection *)connection{    done = YES;    UIImage *img = [[UIImage alloc] initWithData:buffer];    [downloadImageDelegate imageDownLoadFinished:img];}-(BOOL)isConcurrent {    //返回yes表示支持异步调用,否则为支持同步调用    return YES;    }- (BOOL)isExecuting{    return connection == nil; }- (BOOL)isFinished{    return connection == nil;  }@end





DownLoadImageTask中定义了协议DownLoadImageDelegate,ViewController需要实现协议DownLoadImageDelegate;DownLoadImageTask下载工作完成后,会回调ViewController实现的DownLoadImageDelegate协议中的方法。






2、ViewController.h如下:
#import "DownLoadImageTask.h"@interface ViewController:UIViewController<DownLoadImageDelegate>{}@property(strong,nonatomic)NSOperationQueue *queue;@property(strong,nonatomic)UIImageView *appImgView;@end



ViewController.m如下:
#import "ViewController.h"#import "DownLoadImageTask.h"@implementation ViewController@synthesize queue;@synthesize appImgView;-(void)loadView{    //初始化视图    [self initViews];        //显示等待框    [self showWaiting];    NSString *url = @"http://hiphotos.baidu.com/newwen666666/pic/item/01ec7750863e49600cf3e3cc.jpg";    int index = 1;        DownLoadImageTask *task = [[DownLoadImageTask alloc]initWithURLString:url];    task.downloadImageDelegate = self;    task.operationId = index++;        queue = [[NSOperationQueue alloc]init];    [queue addOperation:task];}//初始化视图组件-(void)initViews{    CGRect frame = [UIScreen mainScreen].applicationFrame;    UIView *appView = [[UIView alloc]initWithFrame:frame];    self.view = appView;    [self.view setBackgroundColor:[UIColor colorWithWhite:1.0 alpha:1.0]];        frame = CGRectMake(0, 0, frame.size.width, frame.size.height);    appImgView = [[UIImageView alloc]initWithFrame:frame];        [self.view addSubview:appImgView];}//展示等待框-(void)showWaiting{    CGRect frame = CGRectMake(0, -20, 320, 480);    int x = frame.size.width;      int progressWidth = 150;    int progressHeight = 32;    frame = CGRectMake((x-progressWidth)/2, 100, progressWidth, progressHeight);    UIProgressView *progress = [[UIProgressView alloc]initWithProgressViewStyle:UIProgressViewStyleBar];    progress.frame = frame;    progress.progress = 0.0;    progress.backgroundColor = [UIColor whiteColor];        UILabel *showValue = [[UILabel alloc]init];      frame = showValue.frame;      frame.origin.x = CGRectGetMaxX(progress.frame)+10;      frame.origin.y = CGRectGetMinY(progress.frame);      frame.size.width = 45;      frame.size.height = 15;      showValue.frame = frame;      showValue.backgroundColor = [UIColor redColor];      showValue.text = @"0.0";              int progressIndWidth = 32;    int progressIndHeight = 32;    frame = CGRectMake((x-progressIndWidth)/2, 100+32, progressIndWidth, progressIndHeight);    UIActivityIndicatorView *progressInd = [[UIActivityIndicatorView alloc]initWithFrame:frame];    [progressInd startAnimating];    progressInd.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;        frame = CGRectMake((x-70)/2, 100+32+32, 80, 20);    UILabel *waitinglabel = [[UILabel alloc]initWithFrame:frame];    waitinglabel.text = @"正在下载应用程序图片...";    waitinglabel.textColor = [UIColor redColor];    waitinglabel.font = [UIFont systemFontOfSize:15];    waitinglabel.backgroundColor = [UIColor clearColor];        frame = CGRectMake(0, -20, 320, 480);    UIView *theView = [[UIView alloc]initWithFrame:frame];    theView.backgroundColor = [UIColor blackColor];    theView.alpha = 0.7;        [progress setTag:100];    [theView addSubview:progress];    [showValue setTag:101];    [theView addSubview:showValue];        [theView addSubview:progressInd];    [theView addSubview:waitinglabel];        [theView setTag:110];    [self.view addSubview:theView];}//隐藏等待框-(void)hiddenWaiting{    [[self.view viewWithTag:110]removeFromSuperview];}- (void)viewDidUnload{    [super viewDidUnload];    // Release any retained subviews of the main view.}- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);}#pragma mark DownLoadImageDelegate methods//展示下载完毕的图片-(void)imageDownLoadFinished:(UIImage *)img{    //退出等待框    [self hiddenWaiting];    [appImgView setImage:img];}//更新进度条的值-(void)updateDownProgress:(double) value{    UIProgressView *progresss = (UIProgressView *)[self.view viewWithTag:100];    UILabel *showValue = (UILabel*)[self.view viewWithTag:101];    progresss.progress = value;    showValue.text = [NSString stringWithFormat:@"%.1f%",(double)(value*100)];}@end




  相关解决方案