NSOperation简单使用01

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---<NSThread: 0x7fe2b3c65430>{number = 5, name = (null)}

NSOperation[1664:217072] 2---<NSThread: 0x7fe2b3c65020>{number = 3, name = (null)}

NSOperation[1664:217074] 1---<NSThread: 0x7fe2b3e10130>{number = 2, name = (null)}

NSOperation[1664:217073] 3---<NSThread: 0x7fe2b3e0a7d0>{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];

}

时间: 2024-10-04 12:17:32

NSOperation简单使用01的相关文章

iOS开发多线程篇 09 —NSOperation简单介绍

iOS开发多线程篇—NSOperation简单介绍 一.NSOperation简介 1.简单说明 NSOperation的作?:配合使用NSOperation和NSOperationQueue也能实现多线程编程 NSOperation和NSOperationQueue实现多线程的具体步骤: (1)先将需要执行的操作封装到一个NSOperation对象中 (2)然后将NSOperation对象添加到NSOperationQueue中 (3)系统会?动将NSOperationQueue中的NSOpe

iOS开发多线程篇—NSOperation简单介绍

iOS开发多线程篇—NSOperation简单介绍 一.NSOperation简介 1.简单说明 NSOperation的作?:配合使用NSOperation和NSOperationQueue也能实现多线程编程 NSOperation和NSOperationQueue实现多线程的具体步骤: (1)先将需要执行的操作封装到一个NSOperation对象中 (2)然后将NSOperation对象添加到NSOperationQueue中 (3)系统会?动将NSOperationQueue中的NSOpe

NSOperation简单介绍

NSOperation简单介绍 一.NSOperation简介 1.简单说明 NSOperation的作?:配合使用NSOperation和NSOperationQueue也能实现多线程编程 NSOperation和NSOperationQueue实现多线程的具体步骤: (1)先将需要执行的操作封装到一个NSOperation对象中 (2)然后将NSOperation对象添加到NSOperationQueue中 (3)系统会?动将NSOperationQueue中的NSOperation取出来

hdu 1864 最大报销额 模型为简单的01背包

很简单的01背包,但是题目还是很蛋疼的注意题目中600,和1000这两个数,还有就是double和int的转换,1A了感觉还是不错的 /************************************************************************* > File Name: hdu1864.cpp > Author: yang > Mail:[email protected] > Created Time: 2014年08月23日 星期六 14:0

【iOS开发】NSOperation简单介绍

iOS开发多线程篇—NSOperation简单介绍 一.NSOperation简介 1.简单说明 NSOperation的作?:配合使用NSOperation和NSOperationQueue也能实现多线程编程 NSOperation和NSOperationQueue实现多线程的具体步骤: (1)先将需要执行的操作封装到一个NSOperation对象中 (2)然后将NSOperation对象添加到NSOperationQueue中 (3)系统会?动将NSOperationQueue中的NSOpe

OS开发多线程篇—NSOperation简单介绍

iOS开发多线程篇—NSOperation简单介绍 一.NSOperation简介 1.简单说明 NSOperation的作?:配合使用NSOperation和NSOperationQueue也能实现多线程编程 NSOperation和NSOperationQueue实现多线程的具体步骤: (1)先将需要执行的操作封装到一个NSOperation对象中 (2)然后将NSOperation对象添加到NSOperationQueue中 (3)系统会?动将NSOperationQueue中的NSOpe

HDU 2602 (简单的01背包) Bone Collector

很标准的01背包问题 1 //#define LOCAL 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 using namespace std; 6 7 const int maxn = 1000 + 10; 8 int w[maxn], v[maxn], dp[maxn]; 9 10 int main(void) 11 { 12 #ifdef LOCAL 13 freopen(&qu

Android Interface(UI) 界面控件简单介绍01

1.TextView:显示文本 常用的属性设置:android:textIsSelectable="true" 设置文本内容可选(触发系统的复制粘贴功能)android:drawableLeft="@mipmap/ic_launcher" 设置文本内容的图标其它包括drawableRight, drawableTop, drawableBottom, drawableStart, drawableEndandroid:text="Hello World!&

四:多线程--NSOperation简单介绍

一.NSOperation简介 1.NSOperation的作?:配合使用NSOperation和NSOperationQueue也能实现多线程编程 NSOperation和NSOperationQueue实现多线程的具体步骤: (1)先将需要执行的操作封装到一个NSOperation对象中 (2)然后将NSOperation对象添加到NSOperationQueue中 (3)系统会?动将NSOperationQueue中的NSOperation取出来 (4)将取出的NSOperation封装的