NSOperation简单介绍

a. 是OC语言中基于GCD的面向对象的封装

b. 使用起来比GCD更加简单(面向对象)

c. 提供了一些用GCD不好实现的功能

d. 苹果推荐使用,使用NSOperation不用关心线程以及线程的生命周期

. NSOperation是一个抽象类

i. 不能直接使用(方法没有实现)

ii. 约束子类都具有共同的属性和方法

. NSOperation的子类

i. NSInvocationOperation

ii. NSBlockOperation

.NSOperationQueue 队列

NSInvocationOperation代码演示

. 执行操作

    //创建操作

    NSInvocationOperation* op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadFile:) object:@"fileName"];

    //在当前线程执行方法(开始执行操作)

    [op start];

. 把操作添加到队列(并开始异步执行) //创建操作

    NSInvocationOperation* op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadFile:) object:@"fileName"];

        //将操作添加到队列,会自动异步调用方法

        NSOperationQueue *queue = [[NSOperationQueue alloc] init];

        [queue addOperation:op];

- (void)downloadFile:(id)object { NSLog(@"下载:%@----线程:%@", object, [NSThread currentThread]); }

. 开启多个线程, 不会顺序执行-- -》GCD并发队列, 异步执行

    //队列

    NSOperationQueue* queue = [[NSOperationQueue alloc] init];

    for (int i = ; i < ; i++) {

    //创建操作

    NSInvocationOperation* op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadFile:) object:@(i)];

    //将操作添加到队列,会自动异步调用方法

    [queue addOperation:op];

}

- (void)downloadFile:(id)object

{

    NSLog(@"下载:%@----线程:%@", object, [NSThread currentThread]);

NSBlockOperation代码演示

//1. NSBlockOperation

//队列

NSOperationQueue* queue = [[NSOperationQueue alloc] init];

for (int i = ; i < ; i++) { //操作

    NSBlockOperation* op = [NSBlockOperation blockOperationWithBlock:^{

        NSLog(@"down %d %@", i, [NSThread currentThread]);

    }];

    [queue addOperation:op];

}

//2. NSOperationQueue添加block的operation代码更简练

NSOperationQueue* queue = [[NSOperationQueue alloc] init];

for (int i = ; i < ; i++) {

    [queue addOperationWithBlock:^{

        NSLog(@"down %d %@", i, [NSThread currentThread]);

    }];

}

//3. 全局操作队列(controller的全局), 调度所有的异步操作 定义属性

@property (nonatomic, strong) NSOperationQueue* queue;

//懒加载队列

- (NSOperationQueue*)queue

{

    if (_queue == nil) {

        _queue = [[NSOperationQueue alloc] init];

    }

    return _queue;

}

for (int i = ; i < ; i++) {

    [self.queue addOperationWithBlock:^{

        NSLog(@"down %d %@", i, [NSThread currentThread]);

    }];

}

//4. 监听操作完成

[op1 setCompletionBlock:^{

    NSLog(@".....");

}];

线程间通讯

//1. 主队列 添加到主队列的操作,最终都执行在主线程上

[NSOperationQueue mainQueue]

     //获取当前操作所在的队列

    [NSOperationQueue currentQueue]

    [self.queue addOperationWithBlock:^{

        NSLog(@"异步执行的 %@", [NSThread currentThread]);

         //获取主队列

        [[NSOperationQueue mainQueue] addOperationWithBlock:^{

            NSLog(@"主线程?%@", [NSThread currentThread]);

            //当前队列是谁呢? 正在执行操作的队列

            [[NSOperationQueue currentQueue] addOperationWithBlock:^{

                NSLog(@"当前队列是谁呢 %@", [NSThread currentThread]);

            }];

        }];

    }];

NSOperation中的方便的使用 

1. 最大并发数

self.queue.maxConcurrentOperationCount = ;

for (int i = ; i < ; i++) {

    [self.queue addOperationWithBlock:^{ //加上此代码后执行的过程?

        [NSThread sleepForTimeInterval:];

        NSLog(@"%@---%d", [NSThread currentThread], i);

    }];

}

• 执行过程

、把操作添加到队列 self.queue addOperationWithBlock

、去线程池去取空闲的线程, 如果没有就创建线程

、把操作交给从线程池中取出的线程执行

、执行完成后, 把线程再放回线程池中

、重复2, , 4知道所有的操作都执行完

2. 队列的暂定/继续 取消

. 暂停 判断队列是否是挂起状态时, 并不会判断队列中是否有操作 我们可以先判断下队列是否为空
if (self.queue.operationCount == )
{
NSLog(@"队列中没有操作");
return;
}
. 继续 - (IBAction)pause
{
if (self.queue.operationCount == ) {
NSLog(@"队列中没有操作");
return;
}
if (self.queue.isSuspended) { //继续
self.queue.suspended = NO;
NSLog(@"继续");
}
else {
//挂起(暂定)
self.queue.suspended = YES; NSLog(@"暂停");
}
//当前队列的操作数
NSLog(@"%lu", self.queue.operationCount);
}
. 取消(清除队列中的操作) - (IBAction)cancel
{
[self.queue cancelAllOperations];
NSLog(@"取消");
NSLog(@"%lu", self.queue.operationCount);
}
. 等待队列中的操作执行完毕
//等待队列中的操作执行完毕,会阻塞
[self.queue waitUntilAllOperationsAreFinished]; NSLog(@"over");

依赖关系 

. 模拟软件的部分升级
//依赖关系
//模拟软件的部分升级
//下载压缩包
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"下载 %@",[NSThread currentThread]); }];
//解压,复制到相应目录
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"解压 %@",[NSThread currentThread]); }];
//通知用户
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"通知用户升级完成 %@",[NSThread currentThread]); }];
//设置操作的依赖关系
[op2 addDependency:op1];
[op3 addDependency:op2];
//添加操作
//waitUntilFinished YES 等待所有的操作执行完成 会阻塞窗体的执行 //waitUntilFinished NO 不等待
[self.queue addOperations:@[op1,op2,op3] waitUntilFinished:NO]; NSLog(@"over"); . 循环依赖 发生循环依赖,程序不会死锁。界面也不会阻塞,操作不会执行 [op2 addDependency:op1];
[op3 addDependency:op2];
[op1 addDependency:op3]; . 依赖关系可以快队列执行
//设置操作的依赖关系 [op2 addDependency:op1]; [op3 addDependency:op2];
[self.queue addOperations:@[op1,op2] waitUntilFinished:NO]; NSLog(@"over");
[[NSOperationQueue mainQueue] addOperation:op3];

NSOperation基本使用的更多相关文章

  1. iOS多线程之9.自定义NSOperation

      本文主要讲如何自定义NSOperation,以及自定义NSOperation的一些注意事项,以下载图片为例. 新建一个类,继承于NSOperation. CustomOperation.h 代码 ...

  2. iOS多线程之8.NSOPeration的其他用法

      本文主要对NSOPeration的一些重点属性和方法做出介绍,以便大家可以更好的使用NSOPeration. 1.添加依赖 - (void)addDependency:(NSOperation * ...

  3. iOS多线程之7.NSOperation的初识

    NSOperation和GCD一样,不用我们管理线程的生命周期,加锁等问题,只要把操作封装进NSOperation中,系统会自动帮我们创建线程,执行操作.而且他是面向对象的,我们看起来更容易理解,使用 ...

  4. 4.4 多线程进阶篇<下>(NSOperation)

    本文并非最终版本,如有更新或更正会第一时间置顶,联系方式详见文末 如果觉得本文内容过长,请前往本人"简书" 本文源码 Demo 详见 Github https://github.c ...

  5. 认识和使用NSOperation

    原文链接:http://www.jianshu.com/p/2de9c776f226 NSOperation是OC中多线程技术的一种,是对GCD的OC包装.它包含队列(NSOperationQueue ...

  6. 多线程下NSOperation、NSBlockOperation、NSInvocationOperation、NSOperationQueue的使用

    本篇文章主要介绍下多线程下NSOperation.NSBlockOperation.NSInvocationOperation.NSOperationQueue的使用,列举几个简单的例子. 默认情况下 ...

  7. iOS NSOperation 封装 通知实现界面更新

    #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @interface MYOperation : NSOpe ...

  8. iOS NSOperation 异步加载图片 封装NSOperation 代理更新

    #import <Foundation/Foundation.h> @class MYOperation; @protocol MYOperationDelecate <NSObje ...

  9. 3.多线程NSOperation

    1.NSOperation的基本操作 使用NSOperation的两个子类,NSInvocationOperation 和 NSBlockOperation 创建操作,然后将操作添加到队列中去执行 / ...

  10. NSOperation的start与main,并发与非并发。

    http://blog.csdn.net/a2331046/article/details/52294006 在ios4以前,只有非并发的情况下,队列会为operation开启一个线程来执行.如果是并 ...

随机推荐

  1. 通过telnet连接查看memcache服务器(转)

    memcache作为一款优秀的进程外缓存,常常被运用于高并发系统架构中.这里主要谈谈怎么通过telnet工具,查看memcache运行状况并对其key进行管理维护.假设memcache安装目录:/us ...

  2. 基于TcpListener的web服务器

    写在前面 上篇文章根据<asp.net 本质论>书上提供的例子,实现了一个简单的web服务器,本篇文章将介绍另一种实现方式——基于TcpListener的web服务器. TcpListen ...

  3. strstr 函数用法

    strstr 编辑 strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串.如果是,则该函数返回str2在str1中首次出现的地址:否则,返回NULL. C语言函数 编辑 ...

  4. spring JTA多数据源事务管理详细教程

    <context:annotation-config /> <!-- 使用注解的包路径 --> <context:component-scan base-package= ...

  5. Wormholes(Bellman-ford)

    Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 33008   Accepted: 12011 Descr ...

  6. 在C/C++程序里打印调用栈信息

    我们知道,GDB的backtrace命令可以查看堆栈信息.但很多时候,GDB根本用不上.比如说,在线上环境中可能没有GDB,即使有,也不太可能让我们直接在上面调试.如果能让程序自己输出调用栈,那是最好 ...

  7. 对大一新生开始学习C语言课程谈几点看法

    大家好,首先祝贺大家进入了大学,迈入了大学的校门,也意味着开始了新的征程,希望大家能够有一个美好的大学四年. 先做下自我介绍,我叫李帅阳,(大家可以称呼我 李老师,或是班助,或是...)这是在邹欣老师 ...

  8. Nmap备忘单:从探索到漏洞利用(Part3)

    众所周知NMAP是经常用来进行端口发现.端口识别.除此之外我们还可以通过NMAP的NSE脚本做很多事情,比如邮件指纹识别,检索WHOIS记录,使用UDP服务等. 发现地理位置 Gorjan Petro ...

  9. 对比WDCP面板与AMH面板的区别与选择

    转载: http://www.laozuo.org/2760.html | 老左博客 随着VPS主机的性价比提高(其实就是降价)我们很多站长会越来越多的选择使用VPS搭建网站或者运营一些项目,相比较而 ...

  10. HXOI 2014 PSet 4 Day 1 一模04日1 题解

    1. 最小花费(money.pas/c/cpp) 问题描述 在n个人中,某些人的银行账号之间可以互相转账.这些人之间转账的手续费各不相同.给定这些人之间转账时需要从转账金额里扣除百分之几的手续费,请问 ...