NSOperation使用
1.继承NSOperation
DownLoadImageTask.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@protocol DownLoadImageDelegate;//声明 @interface DownLoadImageTask : NSOperation<NSURLConnectionDelegate>{
long long totalLength;
BOOL done;
} @property(nonatomic,weak) 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
#import "DownLoadImageTask.h"
@implementation DownLoadImageTask
- (id)initWithURLString:(NSString *)url{
NSLog(@"url=%@",url);
self = [super init];
if(self){
self.request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
self.buffer = [NSMutableData data];
}
return self;
} //主要处理方法
-(void)start{ //或者main
NSLog(@"DownLoadImageTask-start"); if(![self isCancelled]){
//暂停一下
[NSThread sleepForTimeInterval:];
//设置connection及其代理
self.connection = [[NSURLConnection alloc]initWithRequest:self.request delegate:self];
if(self.connection!=nil){
while(!done){
[[NSRunLoop currentRunLoop]runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
}
}
} -(void)httpConnectEndWithError{
//[self hiddenWaiting];
NSLog(@"httpConnectEndWithError");
} -(void)dealloc{
self.buffer = nil;
self.connection = nil;
self.request = nil;
self.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];
[self.buffer setLength:];
} //收到响应
- (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...");
[self.buffer appendData:data]; double progressValue = totalLength==?:((double)([self.buffer length])/(double)totalLength);
//更新进度条值
//[(NSObject *)self.downloadImageDelegate performSelectorOnMainThread:@selector(updateDownProgress:) withObject:[NSNumber numberWithDouble:progressValue] waitUntilDone:NO];//主线程中执行代理方法
[self.downloadImageDelegate updateDownProgress:progressValue];
} //下载完毕
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
done = YES;
UIImage *img = [[UIImage alloc] initWithData:self.buffer];
//[(NSObject *)self.downloadImageDelegate performSelectorOnMainThread:@selector(imageDownLoadFinished:) withObject:img waitUntilDone:NO];
[self.downloadImageDelegate imageDownLoadFinished:img];
} -(BOOL)isConcurrent {
//返回yes表示支持异步调用,否则为支持同步调用
return YES; } - (BOOL)isExecuting{
return self.connection == nil;
} - (BOOL)isFinished{
return self.connection == nil;
} @end
2.在ViewController中调用NSOperation子类
ViewController.h
#import <UIKit/UIKit.h>
#import "DownLoadImageTask.h" @interface ViewController:UIViewController<DownLoadImageDelegate> @property(strong,nonatomic)NSOperationQueue *queue;
@property(strong,nonatomic)UIImageView *appImgView; @property (strong,nonatomic)UIImage *image1;
@property (strong,nonatomic)UIImage *image2; @end
ViewController.m
#import "ViewController.h"
#import "DownLoadImageTask.h" typedef void (^downLoad1)();
@interface ViewController() @property (nonatomic,strong)downLoad1 downloadBlock; @end @implementation ViewController #pragma mark - LoadView
-(void)loadView{
//初始化视图
[self initViews]; //显示等待框
[self showWaiting];
NSString *url = @"http://hiphotos.baidu.com/newwen666666/pic/item/01ec7750863e49600cf3e3cc.jpg";
DownLoadImageTask *task = [[DownLoadImageTask alloc]initWithURLString:url];
task.downloadImageDelegate = self;
//task.operationId = index++; self.queue = [[NSOperationQueue alloc]init];
[self.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(, , frame.size.width, frame.size.height);
_appImgView = [[UIImageView alloc]initWithFrame:frame];
[self.view addSubview:_appImgView];
} //展示等待框
-(void)showWaiting{
CGRect frame = CGRectMake(, -, , );
int x = frame.size.width; int progressWidth = ;
int progressHeight = ;
frame = CGRectMake((x-progressWidth)/, , 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)+;
frame.origin.y = CGRectGetMinY(progress.frame);
frame.size.width = ;
frame.size.height = ;
showValue.frame = frame;
showValue.backgroundColor = [UIColor redColor];
showValue.text = @"0.0"; int progressIndWidth = ;
int progressIndHeight = ;
frame = CGRectMake((x-progressIndWidth)/, +, progressIndWidth, progressIndHeight);
UIActivityIndicatorView *progressInd = [[UIActivityIndicatorView alloc]initWithFrame:frame];
[progressInd startAnimating];
progressInd.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge; frame = CGRectMake((x-)/, ++, , );
UILabel *waitinglabel = [[UILabel alloc]initWithFrame:frame];
waitinglabel.text = @"正在下载应用程序图片...";
waitinglabel.textColor = [UIColor redColor];
waitinglabel.font = [UIFont systemFontOfSize:];
waitinglabel.backgroundColor = [UIColor clearColor]; frame = CGRectMake(, , , );
UIView *theView = [[UIView alloc]initWithFrame:frame];
theView.backgroundColor = [UIColor blackColor];
theView.alpha = 0.7; [progress setTag:];
[theView addSubview:progress];
[showValue setTag:];
[theView addSubview:showValue]; [theView addSubview:progressInd];
[theView addSubview:waitinglabel]; [theView setTag:];
[self.view addSubview:theView];
} #pragma mark - ViewDidLoad -(void)viewDidLoad{
NSLog(@"%@",self.view.subviews);
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(, , , );
button.center = CGPointMake(self.view.center.x,self.view.center.y +);
[button addTarget:self action:@selector(downloadImage:) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:@"下载图片" forState:UIControlStateNormal];
[self.view addSubview:button];
__weak typeof(self) weakSelf = self; self.downloadBlock = ^{
weakSelf.appImgView.image = weakSelf.image1;
[NSTimer scheduledTimerWithTimeInterval:2.0 target:weakSelf selector:@selector(updateImage) userInfo:nil repeats:NO];
};
} - (void)updateImage{
self.appImgView.image = self.image2;
} #pragma mark - clickAction
- (void)downloadImage:(UIButton *)sender{
[self downloadImages];
} #pragma mark - DownLoadImages - (void)downloadImages {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ); // 异步下载图片
dispatch_async(queue, ^{
// 创建一个组
dispatch_group_t group = dispatch_group_create(); __block UIImage *image1 = nil;
__block UIImage *image2 = nil; // 关联一个任务到group
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{
// 下载第一张图片
NSString *url1 = @"http://car0.autoimg.cn/upload/spec/9579/u_20120110174805627264.jpg";
image1 = [self imageWithURLString:url1];
}); // 关联一个任务到group
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{
// 下载第一张图片
NSString *url2 = @"http://hiphotos.baidu.com/lvpics/pic/item/3a86813d1fa41768bba16746.jpg";
image2 = [self imageWithURLString:url2];
}); // 等待组中的任务执行完毕,回到主线程执行block回调
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
self.image1 = image1;
self.image2 = image2;
self.downloadBlock();
// 千万不要在异步线程中自动释放UIImage,因为当异步线程结束,异步线程的自动释放池也会被销毁,那么UIImage也会被销毁
});
});
} - (UIImage *)imageWithURLString:(NSString *)urlString {
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [NSData dataWithContentsOfURL:url];
// 这里并没有自动释放UIImage对象
return [[UIImage alloc] initWithData:data];
} #pragma mark - DownLoadImageDelegate methods
//展示下载完毕的图片
-(void)imageDownLoadFinished:(UIImage *)img{
//退出等待框
[self hiddenWaiting];
[self.appImgView setImage:img];
NSLog(@"%@",self.view.subviews); } //更新进度条的值
-(void)updateDownProgress:(double) value{
UIProgressView *progresss = (UIProgressView *)[self.view viewWithTag:];
UILabel *showValue = (UILabel*)[self.view viewWithTag:];
progresss.progress = value;
showValue.text = [NSString stringWithFormat:@"%.1f%%",(double)(value*)];
} //隐藏等待框
-(void)hiddenWaiting{
[[self.view viewWithTag:]removeFromSuperview];
} - (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
} - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
} @end
NSOperation使用的更多相关文章
- iOS多线程之9.自定义NSOperation
本文主要讲如何自定义NSOperation,以及自定义NSOperation的一些注意事项,以下载图片为例. 新建一个类,继承于NSOperation. CustomOperation.h 代码 ...
- iOS多线程之8.NSOPeration的其他用法
本文主要对NSOPeration的一些重点属性和方法做出介绍,以便大家可以更好的使用NSOPeration. 1.添加依赖 - (void)addDependency:(NSOperation * ...
- iOS多线程之7.NSOperation的初识
NSOperation和GCD一样,不用我们管理线程的生命周期,加锁等问题,只要把操作封装进NSOperation中,系统会自动帮我们创建线程,执行操作.而且他是面向对象的,我们看起来更容易理解,使用 ...
- 4.4 多线程进阶篇<下>(NSOperation)
本文并非最终版本,如有更新或更正会第一时间置顶,联系方式详见文末 如果觉得本文内容过长,请前往本人"简书" 本文源码 Demo 详见 Github https://github.c ...
- 认识和使用NSOperation
原文链接:http://www.jianshu.com/p/2de9c776f226 NSOperation是OC中多线程技术的一种,是对GCD的OC包装.它包含队列(NSOperationQueue ...
- 多线程下NSOperation、NSBlockOperation、NSInvocationOperation、NSOperationQueue的使用
本篇文章主要介绍下多线程下NSOperation.NSBlockOperation.NSInvocationOperation.NSOperationQueue的使用,列举几个简单的例子. 默认情况下 ...
- iOS NSOperation 封装 通知实现界面更新
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @interface MYOperation : NSOpe ...
- iOS NSOperation 异步加载图片 封装NSOperation 代理更新
#import <Foundation/Foundation.h> @class MYOperation; @protocol MYOperationDelecate <NSObje ...
- 3.多线程NSOperation
1.NSOperation的基本操作 使用NSOperation的两个子类,NSInvocationOperation 和 NSBlockOperation 创建操作,然后将操作添加到队列中去执行 / ...
- NSOperation的start与main,并发与非并发。
http://blog.csdn.net/a2331046/article/details/52294006 在ios4以前,只有非并发的情况下,队列会为operation开启一个线程来执行.如果是并 ...
随机推荐
- Android--UI之AutoCompleteTextView
前言 之前讲过EditText,有兴趣的朋友可以看一下.这篇博客主要说明的是自动完成文本框,它实际上也是一个文本编辑框,可以理解为对EditText功能的扩展,它对输入的内容可以进行提示并且自动完成. ...
- java中线程分两种,守护线程和用户线程。
java中线程分为两种类型:用户线程和守护线程. 通过Thread.setDaemon(false)设置为用户线程: 通过Thread.setDaemon(true)设置为守护线程. 如果不设置次属性 ...
- HttpClient session
session概述 session机制 session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息. 当程序需要为某个客户端的请求创建一个session ...
- VirtualBox centos 6.5 minimal 开启网络
默认情况下载的centos 6.5 minimal是不开启网卡功能的,按照下面的步骤开启网卡. vi /etc/sysconfig/network-script/ifcfg-eth0 将其中的 ONB ...
- c++对象创建带括号与无括号的区别
class Test{public: Test() {} Test(int a) {}} 1.栈上创建对象 1.1 无括号 Test a; // 调用默认构造函数,栈上分配内存创建对象 1.2 有括号 ...
- H5canvas赛车游戏-基于lufylegend引擎
lufylegend引擎是canvas游戏中,比较简单的引擎之一,它不需要配置环境,类似引入jquery包的方式,引用对应js文件即可 lufylegend官方网站:http://www.lufyle ...
- 微博转发关系采集,可拓展关键字采集,评论采集(Java版)
微博模拟登录获取cookis,配置采集深度,采集一条微博转发关系页面,同时解析页面,生成一条微博的传播图,数据集可做微博影响力分析和传播分析 gitthub:https://github.com/ch ...
- ubuntu14 谷歌输入法
sudo apt-get install ibus-googlepinyin 装完重启即可: (在右上角语言处右键,添加text entry)
- UOJ 做题记录
UOJ 做题记录 其实我这么弱> >根本不会做题呢> > #21. [UR #1]缩进优化 其实想想还是一道非常丝播的题目呢> > 直接对于每个缩进长度统计一遍就好 ...
- 关于Jquery学习的几点反思
1.应用的API插件时,先看说明文档,仔细看,多花点时间也没关系. 2.写出你要完成工作的几个步骤,细化你的工作.保证每一步结果都是正确(特别是在用你不会的东西的时候),这样看起来是在浪费时间,但是最 ...