博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NSOperation简单使用01
阅读量:6121 次
发布时间:2019-06-21

本文共 8976 字,大约阅读时间需要 29 分钟。

NSOperation(操作) 是一个抽象类 不能直接使用;NSOperation 有两个直接子类;NSInvocationOperation(调用)和NSBlockOperation(代码块)NSOperation是对GCD的进一步封装,相比于GCD而言,GCD使用方便,适用于简单的线程操作,不能控制NSOperation是可以控制的各个操作之间有依赖关系,可以 - (void)start; - (void)cancel;添加/移除操作依赖- (void)addDependency:(NSOperation *)op;- (void)removeDependency:(NSOperation *)op; 操作必定执行main方法- (void)main; 实例代码:- (void)viewDidLoad {    [super viewDidLoad];    // NSOperation本质是对GCD的封装    //    NSOperation    NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(testLongs) object:nil];    // 默认情况下调用start方法之后不会开启新的线程,只会在当前线程中执行操作    [operation1 start];    // 只有将操作放入到操作队列中(NSOperationQueue)中,才会异步执行操作    }- (void)testLongs {    NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/new/images/angle00.png"];    NSData *data = [NSData dataWithContentsOfURL:url];    UIImage *image = [UIImage imageWithData:data];    NSLog(@"%@",[NSThread currentThread]);    self.imageIcon1.image = image;}- (UIImageView *)imageIcon1{        if (_imageIcon1 == nil) {        _imageIcon1 = [[UIImageView alloc] initWithFrame: CGRectMake(20, 20, 200, 200)];        [self.view addSubview:_imageIcon1];            }    return _imageIcon1;}  // 只有将操作放入到操作队列中(NSOperationQueue)中,才会异步执行操作 [[NSBlockOperation blockOperationWithBlock:^{    NSData *data = [NSData dataWithContentsOfURL:self.url];    UIImage *image = [UIImage imageWithData:data];    NSLog(@"%@",[NSThread currentThread]);    self.imageIcon2.image = image;}] start]; NSBlockOperation 实例: NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{        NSLog(@"1----%@",[NSThread currentThread]);    NSData *data = [NSData dataWithContentsOfURL:self.url];    UIImage *image = [UIImage imageWithData:data];    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{        self.imageIcon1.image = image;    });}];// 添加多个操作[blockOperation addExecutionBlock:^{    NSLog(@"2----%@",[NSThread currentThread]);    NSData *data = [NSData dataWithContentsOfURL:self.url];    UIImage *image = [UIImage imageWithData:data];    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{        self.imageIcon2.image = image;    });}];[blockOperation addExecutionBlock:^{    NSLog(@"3----%@",[NSThread currentThread]);    NSData *data = [NSData dataWithContentsOfURL:self.url];    UIImage *image = [UIImage imageWithData:data];    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{        self.imageIcon3.image = image;    });}];// 只要NSBlockOperation中封装的操作数 > 1 调用star方法后,会开启多条线程多个任务是同时执行的// 只要NSBlockOperation中封装的操作数 == 1 时 调用start方法后不会开启新线程(只在主线程中执行操作)[blockOperation start];    *操作队列:(NSOperationQueue) 实例代码: - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{        // 创建操作    NSBlockOperation *blockOp = [NSBlockOperation blockOperationWithBlock:^{        NSLog(@"1---%@",[NSThread currentThread]);        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{            self.imageIcon1.image = [self imageWithURL:self.url];        });    }];    [blockOp addExecutionBlock:^{        NSLog(@"2---%@",[NSThread currentThread]);        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{            self.imageIcon2.image = [self imageWithURL:self.url];        });    }];    [blockOp addExecutionBlock:^{        NSLog(@"3---%@",[NSThread currentThread]);        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{            self.imageIcon3.image = [self imageWithURL:self.url];        });    }];    [blockOp addExecutionBlock:^{        NSLog(@"4---%@",[NSThread currentThread]);        // [self imageWithURL:self.url];    }];    [self.myQueue addOperation:blockOp];    //-------------该操作封装的任务是异步执行的,    /*     NSOperation[1664:217071] 4---
{number = 5, name = (null)} NSOperation[1664:217072] 2---
{number = 3, name = (null)} NSOperation[1664:217074] 1---
{number = 2, name = (null)} NSOperation[1664:217073] 3---
{number = 4, name = (null)} NSOperation[1664:217072] 操作完成后的回调代码,,鸡肋 */ blockOp.completionBlock = ^{ NSLog(@"操作完成后的回调代码,,鸡肋"); };} - (UIImage *)imageWithURL:(NSURL *)url{ NSData *data = [NSData dataWithContentsOfURL:url]; return [UIImage imageWithData:data];}/** * 创建一个队列 通过getter方法获取 */- (NSOperationQueue *)myQueue{ if (_myQueue == nil) { _myQueue = [[NSOperationQueue alloc] init]; } return _myQueue;} - (UIImageView *)imageIcon1{ if (_imageIcon1 == nil) { _imageIcon1 = [[UIImageView alloc] initWithFrame: CGRectMake(20, 20, 200, 200)]; [self.view addSubview:_imageIcon1]; } return _imageIcon1;}- (UIImageView *)imageIcon2{ if (_imageIcon2 == nil) { _imageIcon2 = [[UIImageView alloc] initWithFrame: CGRectMake(20, 200, 200, 200)]; [self.view addSubview:_imageIcon2]; } return _imageIcon2;} - (NSURL *)url{ if (_url == nil) { NSString *str = @"http://127.0.0.1/new/images/angle00.png"; _url = [NSURL URLWithString:str]; } return _url;} - (UIImageView *)imageIcon3{ if (_imageIcon3 == nil) { _imageIcon3= [[UIImageView alloc] initWithFrame: CGRectMake(20, 400, 200, 200)]; [self.view addSubview:_imageIcon3]; } return _imageIcon3;} *操作的执行顺序是不确定的:如果要限制操作的执行顺序,可以添加操作依赖- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ __weak typeof(self) wself = self; NSBlockOperation *blockOp1 = [NSBlockOperation blockOperationWithBlock:^{ UIImage *image = [self imageWithURL:self.url]; dispatch_async(dispatch_get_main_queue(), ^{ wself.imageIcon1.image = image; }); }]; NSBlockOperation *blockOp2 = [NSBlockOperation blockOperationWithBlock:^{ UIImage *image = [self imageWithURL:self.url]; dispatch_async(dispatch_get_main_queue(), ^{ wself.imageIcon2.image = image; }); }]; NSBlockOperation *blockOp3 = [NSBlockOperation blockOperationWithBlock:^{ UIImage *image = [self imageWithURL:self.url]; dispatch_async(dispatch_get_main_queue(), ^{ wself.imageIcon3.image = image; }); }]; // blockOp2的执行依赖于blockOp1 (blockOp1执行完后才会执行blockOp2) [blockOp2 addDependency:blockOp1]; [blockOp3 addDependency:blockOp2]; [self.myQueue addOperation:blockOp1]; [self.myQueue addOperation:blockOp2]; [[NSOperationQueue mainQueue] addOperation:blockOp3]; //---------------- // 添加操作依赖注意事项 /** * 1> 需要将操作依赖放在添加操作到队列之前,不然不起丝毫作用 * * 2> 不要循环添加依赖,后果自负 * * 3> 添加到不同队列中的操作,操作依然有效 * * 4> 向队列中添加操作的顺序和操作依赖没有丝毫关系 * * 5> 如果需要对操作做依赖,必须将任务封装在操作中,NSOperation中的操作从某种意义上代替的GCD中的串行队列, * 但是GCD效率更高,不过NSoperation是可以控制的 */} *操作队列: - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{ }]; // 操作队列 // 创建一个非主队列, NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 设置最大并发数量 [queue setMaxConcurrentOperationCount:6]; // queue.maxConcurrentOperationCount = 4; // 将操作添加到队列中 [queue addOperation:blockOperation]; // 取消所有操作 当收到内存警告的时候可以取消所的操作, 取消操作后不会恢复 [queue cancelAllOperations]; // 取消单个操作 [blockOperation cancel]; // 暂停/继续所有操作 [queue setSuspended:YES]; // queue.suspended = YES; queue.suspended = NO; /** * 为什么要取消操作,什么情况下要取消操作 * * 1> 为了用户,为了用户体验,保证程序的流畅 * * 2> 为了管理内存,方式系统在低内存情况下杀死app */} // 接收到内存警告的时候果断取消队列中的所有操作- (void)didReceiveMemoryWarning{ [super didReceiveMemoryWarning]; // [queue cancelAllOperations]; // 取消队列中的所有任务(不可恢复)}// 开始滚动的时候暂停队列中的任务.- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{ // [queue setSuspended:YES]; // 暂停队列中的所有任务}// 滚动结束的时候恢复队列中的任务.- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{ // [queue setSuspended:NO]; // 恢复队列中的所有任务} *线程间通信:0> 子线程下载图片(数据),主线程更新UI- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // __weak typeof(self) weakSelf = self; NSBlockOperation *blockOp = [NSBlockOperation blockOperationWithBlock:^{ // UIImage *image = [self imageWithURL:self.url]; NSData *data = [NSData dataWithContentsOfURL:self.url]; UIImage *image = [UIImage imageWithData:data]; [[NSOperationQueue mainQueue] addOperationWithBlock:^{ self.imageIcon1.image = image; }]; }]; [queue addOperation:blockOp]; }

  

转载于:https://www.cnblogs.com/wolfman4secret/p/4626787.html

你可能感兴趣的文章
10、程序员和编译器之间的关系
查看>>
前端学习之正则表达式
查看>>
配置 RAILS FOR JRUBY1.7.4
查看>>
AndroidStudio中导入SlidingMenu报错解决方案
查看>>
修改GRUB2背景图片
查看>>
Ajax异步
查看>>
好记性不如烂笔杆-android学习笔记<十六> switcher和gallery
查看>>
JAVA GC
查看>>
codeforce 599B Spongebob and Joke
查看>>
3springboot:springboot配置文件(外部配置加载顺序、自动配置原理,@Conditional)
查看>>
9、Dubbo-配置(4)
查看>>
前端第七天
查看>>
BZOJ 2190[SDOI2008]仪仗队
查看>>
图解SSH原理及两种登录方法
查看>>
[转载] 七龙珠第一部——第058话 魔境圣地
查看>>
【总结整理】JQuery基础学习---样式篇
查看>>
查询个人站点的文章、分类和标签查询
查看>>
基础知识:数字、字符串、列表 的类型及内置方法
查看>>
JSP的隐式对象
查看>>
P127、面试题20:顺时针打印矩阵
查看>>