NSOperation具体使用:直接继承NSObject

它的子类有:NSBlockOperation、NSInvocationOperation
还有一个必须的类,队列,用来装创建的线程 NSOperationQueue
 
理解:这个方式是如何实现多线程呢?是通过操作队列来实现多线程的。即主线程是一个主队列,再创建一个队列并将其他的线程加入其中同步执行。如果对共享资源的争夺放在主线程队列中,则不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上;否则的话,仍需要关心数据同步的问题。
 
说明:
一般用子类创建Operation实例来实现多线程,NSBlockOperation、NSInvocationOperation这两种方式均可以使用,前一个采用的是将线程的执行过程封装为block函数,第二个采用的是将线程的执行过程封装为方法。

1、NSOperation的详解:
队列优先级枚举:
typedef NS_ENUM(NSInteger, NSOperationQueuePriority) {

NSOperationQueuePriorityVeryLow = -8L,

NSOperationQueuePriorityLow = -4L,

NSOperationQueuePriorityNormal = 0,

NSOperationQueuePriorityHigh = 4,

NSOperationQueuePriorityVeryHigh = 8

};

属性:
@property (readonly, getter=isCancelled) BOOL cancelled;               //线程是否取消

@property (readonly, getter=isExecuting) BOOL executing;              //线程是否在执行

@property (readonly, getter=isFinished) BOOL finished;                  //线程是否执行完毕

@property (readonly, getter=isConcurrent) BOOL concurrent;          //线程是否并发执行

@property (readonly, getter=isAsynchronous) BOOL asynchronous; //是否线程异步,已经被线程同步覆盖

@property (readonly, getter=isReady) BOOL ready;                       //线程是否处于就绪状态

@property (readonly, copy) NSArray *dependencies;                      //线程依赖的数组

@property NSOperationQueuePriority queuePriority;                  //队列优先级

@property (copy) void (^completionBlock)(void);                           //block函数

@property double threadPriority;                                             //线程优先级

@property NSQualityOfService qualityOfService;                        //服务质量

@property (copy) NSString *name;                                           //线程名字

方法:
- (void)start;   //启动线程
- (void)main;   //主线程

- (void)cancel;//取消线程

- (void)addDependency:(NSOperation *)op; //添加线程依赖(只有上一个线程一直执行,依赖的下一个线程才开始执行)

- (void)removeDependency:(NSOperation *)op; //移除线程依赖

- (void)waitUntilFinished  //等待抢占资源的线程结束

================================================================================

2、NSIndivocationOperation的详解:NSInvocationOperation : NSOperation

属性:

@property (readonly, retain) NSInvocation *invocation;    //线程的调用

@property (readonly, retain) id result;

方法:

//创建线程的实例方法,可以添加线程事件

- (instancetype)initWithTarget:(id)target selector:(SEL)sel object:(id)arg;

//创建线程的实例方法

- (instancetype)initWithInvocation:(NSInvocation *)inv ;

=================================================================

 

3、NSBlockOperation的详解:NSBlockOperation : NSOperation

属性:@property (readonly, copy) NSArray *executionBlocks;   //执行block的线程队列数组

方法:

※创建线程的类方法,执行block函数

+ (instancetype)blockOperationWithBlock:(void (^)(void))block;

※添加执行线程对列block函数

- (void)addExecutionBlock:(void (^)(void))block;

==========================================================

4、NSOperationQueue队列的详解:NSOperationQueue : NSOperation

属性:
@property (readonly, copy) NSArray *operations;           //操作线程数组
@property (readonly) NSUInteger operationCount           //一次能执行的线程数量

@property NSInteger maxConcurrentOperationCount;     // 能并发执行的最大线程数量

@property (getter=isSuspended) BOOL suspended;                  //是否暂时线程

@property (copy) NSString *name ;                                      //线程名字

@property NSQualityOfService qualityOfService;                     //服务质量

@property (assign /* actually retain */) dispatch_queue_t underlyingQueue;

方法:

※添加线程

- (void)addOperation:(NSOperation *)op;

※等待添加线程数组

- (void)addOperations:(NSArray *)ops waitUntilFinished:(BOOL)wait;

※添加线程并执行block函数的实例方法

- (void)addOperationWithBlock:(void (^)(void))block;

※取消所有的线程

- (void)cancelAllOperations;

※等待所有的线程执行完毕

- (void)waitUntilAllOperationsAreFinished;

※当前队列

+ (NSOperationQueue *)currentQueue;

※主队列

+ (NSOperationQueue *)mainQueue;

 
具体举例如下:多线程卖票(将当前票数和线程名字显示在文本视图中)
 
方法一:采用NSOpeartion的子类NSIndivocationOperation创建多线程:
1.文本视图控件并关联以及声明票属性
@interface ViewController ()
{
int tickets;
}
@property (weak, nonatomic) IBOutlet UITextView *textView;

2.设置票数和文本视图

    //准备数据
tickets = ; //设置textView
self.textView.text = @"";
self.textView.layoutManager.allowsNonContiguousLayout = NO;

3.创建NSOperation实例(线程)

//创建NSOperation并加到队列
NSInvocationOperation *operation1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(operationSellMethod:) object:@"售票线程-1"];
NSInvocationOperation *operation2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(operationSellMethod:) object:@"售票线程-2"];

4.将operation加入创建的队列中

    //创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc]init]; //为操作之间添加依赖,只有被依赖的线程执行完,依赖的线程才能执行
//[operation1 addDependency:operation2]; //将opearion放入队列
[queue addOperation:operation1];
[queue addOperation:operation2];

5.更新UI的主线程队列

#pragma mark -更新UI
-(void)appendTextView:(NSString *)text
{
//1.获取原来的内容
NSMutableString *content = [[NSMutableString alloc]initWithString:self.textView.text];
NSRange range = NSMakeRange(content.length, ); //2.追加新的内容
[content appendString:[NSString stringWithFormat:@"\n%@",text]];
[self.textView setText:content]; //3.滚动视图
[self.textView scrollRangeToVisible:range];
}

6.执行对共享抢占资源操作的过程

#pragma mark -执行线程过程

-(void)operationSellMethod:(NSString*)name
{
while (YES)
{
//1.判断是否有票
if (tickets>)
{
//没有将共享抢占资源放到主队列中,仍然要关心数据同步的问题
@synchronized(self)
{
NSString *info = [NSString stringWithFormat:@"总的票数:%d,当前的线程:%@",tickets,name]; [[NSOperationQueue mainQueue]addOperationWithBlock:^{
[self appendTextView:info];
}]; //2.卖票
tickets--;
} //3.线程休眠
if([name isEqualToString:@"售票线程-1"])
{
[NSThread sleepForTimeInterval:0.3f];
}
else
{
[NSThread sleepForTimeInterval:0.2f];
}
}
else
{
//更新UI
NSString *info = [NSString stringWithFormat:@"票已经售完,当前的线程:%@",name];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self appendTextView:info];
}]; //退出线程
break;
}
}
}

方法二:采用NSOpeartion的子类NSBlockOperation创建多线程:

1.文本视图控件并关联以及声明票属性
@interface ViewController ()
{
int tickets;
}
@property (weak, nonatomic) IBOutlet UITextView *textView;

2.设置票数和文本视图

    //准备数据
tickets = 20; //设置textView
self.textView.text = @"";
self.textView.layoutManager.allowsNonContiguousLayout = NO;

3.创建队列和操作block线程

    //创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc]init]; //设置并行的线程数量
//[queue setMaxConcurrentOperationCount:2]; //在队列中添加block的operation
[queue addOperationWithBlock:^{
[self operationSellMethod:@"售票线程-1"];
}]; [queue addOperationWithBlock:^{
[self operationSellMethod:@"售票线程-2"];
}]; NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
[self operationSellMethod:@"售票线程-3"];
}];
[queue addOperation:blockOperation];

4.更新UI的主线程队列

#pragma mark -更新UI
-(void)appendTextView:(NSString *)text
{
//1.获取原来的内容
NSMutableString *content = [[NSMutableString alloc]initWithString:self.textView.text];
NSRange range = NSMakeRange(content.length, ); //2.追加新的内容
[content appendString:[NSString stringWithFormat:@"\n%@",text]];
[self.textView setText:content]; //3.滚动视图
[self.textView scrollRangeToVisible:range];
}

5.执行对共享抢占资源操作的过程

#pragma mark -执行线程过程

#pragma mark -执行线程过程
-(void)operationSellMethod:(NSString*)name
{
while (YES)
{
//1.判断是否有票
if (tickets>)
{
//将共享抢占资源放入主队列,不需要再关心数据同步的问题
[[NSOperationQueue mainQueue]addOperationWithBlock:^{ NSString *info = [NSString stringWithFormat:@"总的票数:%d,当前的线程:%@",tickets,name]; [self appendTextView:info]; //2.卖票
tickets--;
}]; //3.线程休眠
if([name isEqualToString:@"售票线程-1"])
{
[NSThread sleepForTimeInterval:0.3f];
}
else
{
[NSThread sleepForTimeInterval:0.2f];
}
}
else
{
//更新UI
NSString *info = [NSString stringWithFormat:@"票已经售完,当前的线程:%@",name];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self appendTextView:info];
}]; //退出线程
break;
}
}
}

演示结果如下:

 
 

 

iOS:操作队列实现多线程NSOperation的更多相关文章

  1. iOS开发:Swift多线程NSOperation的使用

    介绍: NSOperation是基于GCD实现,封装了一些更为简单实用的功能,因为GCD的线程生命周期是自动管理,所以NSOperation也是自动管理.NSOperation配合NSOperatio ...

  2. iOS边练边学--多线程NSOperation介绍,子类实现多线程的介绍(任务和队列),队列的取消、暂停(挂起)和恢复,操作依赖与线程间的通信

    一.NSOperation NSOperation和NSOperationQueue实现多线程的具体步骤 先将需要执行的操作封装到一个NSOperation对象中 然后将NSOperation对象添加 ...

  3. iOS的三种多线程技术NSThread/NSOperation/GCD

    1.iOS的三种多线程技术 1.NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程) 2.以下两点是苹果专门开发的"并发"技术,使得程序员可以不再去关心 ...

  4. iOS之多线程NSOperation

    目前在 iOS 和 OS X 中有两套先进的同步 API 可供我们使用:NSOperation 和 GCD .其中 GCD 是基于 C 的底层的 API ,而 NSOperation 则是 GCD 实 ...

  5. iOS 多线程 NSOperation、NSOperationQueue

    1. NSOperation.NSOperationQueue 简介 NSOperation.NSOperationQueue 是苹果提供给我们的一套多线程解决方案.实际上 NSOperation.N ...

  6. IOS高级开发之多线程(四)NSOperation

    1.什么是NSOperation,NSOperationQueue? NSOperation是一个抽象的基类,表示一个独立的计算单元,可以为子类提供有用且线程安全的建立状态,优先级,依赖和取消等操作. ...

  7. iOS中的多线程 NSOperation

    在ios中,使用多线程有三种方式,分别是:NSThread.NSOperation和NSOperationQueue.GCD,在本节,主要讲解一下NSOperation的使用. NSOperation ...

  8. swift语言之多线程操作和操作队列(下)———坚持51天吃掉大象(写技术文章)

    欢迎有兴趣的朋友,参与我的美女同事发起的活动<51天吃掉大象>,该美女真的很疯狂,希望和大家一起坚持51天做一件事情,我加入这个队伍,希望坚持51天每天写一篇技术文章.关注她的微信公众号: ...

  9. swift语言之多线程操作和操作队列(上)———坚持51天吃掉大象

    欢迎有兴趣的朋友,参与我的美女同事发起的活动<51天吃掉大象>,该美女真的很疯狂,希望和大家一起坚持51天做一件事情,我加入这个队伍,希望坚持51天每天写一篇技术文章.关注她的微信公众号: ...

随机推荐

  1. datatables的学习总结

    $(document).ready(function() { var oTable= $('#dataTables-example').DataTable({ // searching : false ...

  2. C++智能指针: auto_ptr, shared_ptr, unique_ptr, weak_ptr

    本文参考C++智能指针简单剖析 内存泄露 我们知道一个对象(变量)的生命周期结束的时候, 会自动释放掉其占用的内存(例如局部变量在包含它的第一个括号结束的时候自动释放掉内存) int main () ...

  3. 详解java中的TreeSet集合

    TreeSet是实现Set接口的实现类.所以它存储的值是唯一的,同时也可以对存储的值进行排序,排序用的是二叉树原理.所以要理解这个类,必须先简单理解一下什么是二叉树. 二叉树原理简述 假如有这么一个集 ...

  4. Guava Cache 使用笔记

    https://www.cnblogs.com/parryyang/p/5777019.html https://www.cnblogs.com/shoren/p/guava_cache.html J ...

  5. 安装node的最新版本

    前段时间小试了一下node 这段时间就差不多忘了 恩 然后现在自己想去回顾一下,然后流程想再好好弄一遍 争取掌握node 因为我现在已经安装了 一个node版本 那我想安装最新版本吧 首先,看看你的n ...

  6. Python安装scikit-learn包

    我先是按照网上说的下载了个setuptools,然后直接用这个工具去安装,可是安装scikit-learn包的时候确老是有错误,也不知道错误是啥,所以就不用setuptools来安装了. 我直接下载了 ...

  7. 网站页面SEO的三个标签怎么写有利【转载】

    转载自:代明博客 在SEO界,自从夫唯老师提出“四处一词”的概念以来,不管是搜索引擎还是SEOer,都格外重视页面的三个标签.三个标签书写是否成功,在很大程度上决定了网页是否能有好的排名.今天代明博客 ...

  8. centos7.5英文环境切换到中文环境,再切回中文环境后 ,terminal不能用

    1.查看系统日志 less /var/logs/message May 12 21:54:41 localhost python: SELinux is preventing /usr/libexec ...

  9. 找不到 libgtk-x11-2.0.so.0

    找不到 libgtk-x11-2.0.so.0 安装 yum groupinstall "Development Tools" yum install gtk+-devel gtk ...

  10. Ionic-wechat项目边开发边学(三):自定义样式,指令,服务

    摘要 上一篇文章主要介绍了一个ionic项目的标准目录结构,header标签的使用,以及页面之间的切换.这篇文章实现的功能有: 消息数据的获取, 消息列表的展示, 消息标为已读/未读, 主要涉及的到的 ...