轉載請註明出處,原文網址:http://blog.csdn.net/m_changgong/article/details/8238093 作者:張燕廣
實現的功能:1)演示多線程NSOperation&NSOperationQueue開發;2)子線程中執行下載圖片工作,圖片下載完成前顯示等待框和下載進度條;
關鍵詞:多線程 NSOperation NSOperationQueue 等待框
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
- <span style="font-family:Microsoft YaHei;font-size:18px;">#import "DownLoadImageTask.h"
- @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</span>
2、ViewController.h如下:
- <span style="font-family:Microsoft YaHei;font-size:18px;">#import <UIKit/UIKit.h>
- #import "DownLoadImageTask.h"
- @interface ViewController:UIViewController<DownLoadImageDelegate>{
- }
- @property(strong,nonatomic)NSOperationQueue *queue;
- @property(strong,nonatomic)UIImageView *appImgView;
- @end</span>
ViewController.m如下:
- <span style="font-family:Microsoft YaHei;font-size:18px;">#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</span>
3、效果如下: