多线程——NSOperation
来源:互联网 发布:山东省网络快报 编辑:程序博客网 时间:2024/06/06 10:00
NSOperation和NSOperationQueue实现多线程的具体步骤
先将需要执行的操作封装到一个NSOperation对象中
然后将NSOperation对象添加到NSOperationQueue中
系统会自动将NSOperationQueue中的NSOperation取出来
将取出的NSOperation封装的操作放到一条新线程中执行
NSOperation是个抽象类,并不具备封装操作的能力,必须使用它的子类
使用NSOperation子类的方式有3种
NSInvocationOperation
NSBlockOperation
自定义子类继承NSOperation,实现内部相应的方法
NSInvocationOperation
创建NSInvocationOperation对象
- (id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg;
调用start方法开始执行操作
- (void)start;
一旦执行操作,就会调用target的sel方法
注意
默认情况下,调用了start方法后并不会开一条新线程去执行操作,而是在当前线程同步执行操作
只有将NSOperation放到一个NSOperationQueue中,才会异步执行操作
NSOperationQueue
NSOperationQueue的作用
NSOperation可以调用start方法来执行任务,但默认是同步执行的
如果将NSOperation添加到NSOperationQueue(操作队列)中,系统会自动异步执行NSOperation中的操作
添加操作到NSOperationQueue中
- (void)addOperation:(NSOperation *)op
- (void)addOperationWithBlock:(void (^)(void))block;
例子:NSInvocationOperation
<span style="font-size:18px;">// MARK: 单个NSInvocationOperation使用- (void)opDemo1{ // 1. 创建操作(典型的多态:父类指针指向子类对象) NSOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage:) object:@"Invocation"]; // 2. 启动-- 直接在当前线程执行任务,不开启新的线程// [op start]; // 2. 放到队列 NSOperationQueue *q = [[NSOperationQueue alloc] init]; // 只要把操作添加到队列, ---会自动异步执行调度方法 [q addOperation:op];}#pragma mark - 耗时操作- (void)downloadImage:(id)obj{ NSLog(@"%@---%@", [NSThread currentThread], obj);}</span>
// MARK: 多个NSInvocationOperation使用- (void)opDemo2{ // 队列 (GCD里面的并发(全局)队列使用最多。所以NSOperation技术直接把GCD里面的并发队列封装起来) // NSOperationQueue队列,本质就是GCD里面的并发队列 // 操作就是GCD里面异步执行的任务 NSOperationQueue *q = [[NSOperationQueue alloc] init]; // 把多个操作放到队列 for (int i = 0 ; i < 10; i++) { NSOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage:) object:@"Invocation"]; // 把block操作放到队列 [q addOperation:op]; }}#pragma mark - 耗时操作- (void)downloadImage:(id)obj{ NSLog(@"%@---%@", [NSThread currentThread], obj);}
NSBlockOperation
// MARK: NSBlockOperation更简单的使用- (void)opDemo4{ // 队列 NSOperationQueue *q = [[NSOperationQueue alloc] init]; for (int i = 0; i < 10; i++) { // 不创建操作对象,使用addOperationWithBlock:直接添加操作到队列 [q addOperationWithBlock:^{ NSLog(@"%@---%d", [NSThread currentThread], i); }]; } // 创建并添加一个 NSBlockOperation NSBlockOperation * op1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"op1 --- %@", [NSThread currentThread]); }]; // 添加一个操作 [op1 addExecutionBlock:^{ NSLog(@"op1-1"); }]; [q addOperation:op1]; // 创建并添加一个 NSInvocationOperation NSOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage:) object:@"Invocation"]; [q addOperation:op2];}#pragma mark - 耗时操作- (void)downloadImage:(id)obj{ NSLog(@"%@---%@", [NSThread currentThread], obj);}
最重要的代码:
#pragma mark - 基本使用// MARK: 线程间通信(最重要的代码)- (void)opDemo5{ NSOperationQueue *q = [[NSOperationQueue alloc]init]; [q addOperationWithBlock:^{ NSLog(@"耗时操作....%@", [NSThread currentThread]); // 在主线程更新UI [[NSOperationQueue mainQueue] addOperationWithBlock:^{ NSLog(@"更新UI....%@", [NSThread currentThread]); }]; }];}
最大并发数
什么是并发数
同时执行的任务数
最大并发数的相关方法
- (NSInteger)maxConcurrentOperationCount;
- (void)setMaxConcurrentOperationCount:(NSInteger)cnt;
<span style="font-size:18px;">// MARK: 最大并发数- (void)opDemo6{ // 设置最大的并发数是2 (最大并发数,不是线程的数量。 而是同时执行的操作的数量) self.opQueue.maxConcurrentOperationCount = 2; for (int i = 0; i < 20; i++) { NSOperation *op = [NSBlockOperation blockOperationWithBlock:^{ [NSThread sleepForTimeInterval:1.0]; NSLog(@"%@---%d", [NSThread currentThread], i); }]; [self.opQueue addOperation:op]; }}</span>
队列的取消、暂停、恢复
取消队列的所有操作
- (void)cancelAllOperations;
提示:也可以调用NSOperation的- (void)cancel方法取消单个操作
暂停和恢复队列
- (void)setSuspended:(BOOL)b;//YES代表暂停队列,NO代表恢复队列
- (BOOL)isSuspended;
<pre name="code" class="objc"><span style="font-size:18px;">// MARK: 暂停/继续 (对队列的暂停和继续)- (IBAction)pause{ // 判断操作的数量,当前队列里面是不是有操作 if (self.opQueue.operationCount == 0) { NSLog(@"没有操作"); return; } // 暂停继续 self.opQueue.suspended = !self.opQueue.suspended; if (self.opQueue.suspended) { // 队列的挂起以后,队列里面的操作还在 NSLog(@"暂停"); }else{ NSLog(@"继续"); }}</span>
<span style="font-size:18px;">// MARK: 取消队列里的所有操作// “取消操作,并不会影响队列的挂起状态”- (IBAction)cancelAll{ // 取消队列的所有操作 [self.opQueue cancelAllOperations]; // 取消队列的所有操作,会把任务从队列里面全部删除 NSLog(@"取消所有的操作"); // 取消队列的挂起状态 // (只要是取消了队列的操作,我们就把队列处于启动状态。以便于队列的继续) self.opQueue.suspended = NO;}</span>
操作优先级
设置NSOperation在queue中的优先级,可以改变操作的执行优先级
- (NSOperationQueuePriority)queuePriority;
- (void)setQueuePriority:(NSOperationQueuePriority)p;
优先级的取值
NSOperationQueuePriorityVeryLow = — 8L,
NSOperationQueuePriorityLow = — 4L,
NSOperationQueuePriorityNormal = 0,
NSOperationQueuePriorityHigh = 4,
NSOperationQueuePriorityVeryHigh = 8
操作的监听
可以监听一个操作的执行完毕
- (void (^)(void))completionBlock;
- (void)setCompletionBlock:(void (^)(void))block;
操作依赖
NSOperation之间可以设置依赖来保证执行顺序
比如一定要让操作A执行完后,才能执行操作B,可以这么写
[operationB addDependency:operationA];// 操作B依赖于操作A
可以在不同queue的NSOperation之间创建依赖关系
#pragma mark - 高级操作// MARK: 依赖关系- (void)dependecy{ /** 例子: 1. 下载一个小说的压缩包 2. 解压缩,删除压缩包 3. 更新UI */ NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"1. 下载一个小说的压缩包, %@",[NSThread currentThread]); }]; NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"2. 解压缩,删除压缩包, %@",[NSThread currentThread]); }]; NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"3. 更新UI, %@",[NSThread currentThread]); }]; // 指定任务之间的依赖关系 -- 依赖关系可以跨队列(可以在子线程下载完,到主线程更新UI) [op2 addDependency:op1]; [op3 addDependency:op2]; // 注意点:一定不要出现循环依赖关系// [op1 addDependency:op3]; // waitUntilFinished 类似GCD的调度组的通知 // NO 不等待,会直接执行 NSLog(@"come here"); // YES 等待上面的操作执行结束,再 执行 NSLog(@"come here") [self.opQueue addOperations:@[op1, op2] waitUntilFinished:YES]; // 在主线程更新UI [[NSOperationQueue mainQueue] addOperation:op3]; NSLog(@"come here");}
1 0
- 多线程——NSOperation
- 多线程——NSOperation
- 《多线程——NSOperation》
- 多线程—NSOperation
- 《多线程——自定义NSOperation》
- 多线程—NSOperation和NSOperationQueue
- IOS多线程之——NSOperation和NSOperation Queue
- ios多线程开发——nsoperation详解
- iOS开发——多线程NSOperation
- iOS多线程——NSOperation & NSOperationQueue
- iOS多线程编程——浅谈NSOperation
- IOS开发—多线程之NSOperation介绍
- iOS开发多线程篇—自定义NSOperation
- iOS开发多线程篇—自定义NSOperation
- iOS开发多线程篇—自定义NSOperation
- iOS开发多线程篇—自定义NSOperation
- iOS 多线程篇11—自定义NSOperation
- 多线程开发之NSOperation&NSOperationQueue——异步下载图片
- View 和ViewGroup
- 欢迎使用CSDN-markdown编辑器
- codeforces-446A-DZY Loves Sequences
- java synchronized/wait/notify/互斥/同步
- where 1<> 1 和where 1=1的用法
- 多线程——NSOperation
- photoshop抠图
- QT5.5下的USB HID热插拔检测,未全部完成,聊作记录。
- Android下adb用法总结
- ecshop 数据库调试技巧 【强烈推荐】
- Htmlparser 中的各种Filter介绍
- UML第十四集(18)之交互图、协作图
- C++构造函数和析构函数显示调用
- HP-VB