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 利用SharedPreferences保存与删除 用户登录数据
创建SharedPreferences对象: SharedPreferences sharedPreferences = context.getSharedPreferences("user ...
- Android开发资源推荐第2季
Android CPU监控想法,思路,核心技术和代码 Android App /Task/Stack 总体分析 http://www.eoeandroid.com/thread-161703-1-1. ...
- 我要阻止做java开发的男朋友去创业型公司工作吗?
命这样的标题,我没有瞧不起创业型公司,我只是有点急了,因为男朋友今天晚上就要回复招聘公司了.我先来说说来由吧. 前段时间男朋友离职了,从毕业到现在在公司呆了2年多,因为资金不足导致他做的项目被迫停止了 ...
- ubuntu下如何用命令行运行deb安装包
如果ubuntu要安装新软件,已有deb安装包(例如:iptux.deb),但是无法登录到桌面环境.那该怎么安装?答案是:使用dpkg命令. dpkg命令常用格式如下: sudo dpkg -I ip ...
- cvGet2D的用法
CvScalar s;s = cvGet2D(src, j,i);//获取src图像中坐标为(i,j)的像素点的值s.val[0] 代表src图像BGR中的B通道的值~int nXY = cvGet2 ...
- Android 数据存储之 SQLite数据库存储
----------------------------------------SQLite数据库---------------------------------------------- SQLi ...
- Kali Linux渗透基础知识整理(三):漏洞利用
漏洞利用阶段利用已获得的信息和各种攻击手段实施渗透.网络应用程序漏洞诊断项目的加密通信漏洞诊断是必须执行的.顾名思义,利用漏洞,达到攻击的目的. Metasploit Framework rdeskt ...
- Codeforces 727 D T-shirts Distribution
Description 有 \(6\) 种尺码的衣服,有的人只适合 \(1\) 种衣服,有的人适合相邻的 \(2\) 种,问是否存在合法方案,并输出. Sol 贪心. 首先,只适合 \(1\) 种衣服 ...
- TorgoiseGit配置ssh密钥
TortoiseGit 使用扩展名为ppk的密钥,而不是ssh-keygen生成的rsa密钥.使用命令ssh-keygen -C "邮箱地址" -t rsa产生的密钥在Tortoi ...
- phpcms调用某个栏目下的所有二级栏目
在html中直接这样调用就可以了,subcat中的值为父栏目的catid {loop subcat(93) $r}{/loop} 注意subcat方法的参数,如果只写一个参数,也就是父栏目id,那该父 ...