NSOperation

来源:互联网 发布:反dns劫持 软件 编辑:程序博客网 时间:2024/06/03 21:27

一个线程必须有一个进程,一个程序只可以有一个进程,一个进程可以有多个线程。

进程:

一个运行的app就是一个进程。(如果在面试中遇到问进程中的通信话,那应该就是app之间通信,可分为前台进程和后台进程。前台进程就是打开一个app,后台进程就是这个app后台挂起)。

线程:​

线程是进程的分支,一个进程至少有一个线程,也可以有多个线程。线程是项目中独立的代码,负责资源的调配。线程才是真正的执行单元。

单线程:​

只有一条线程来执行方法。只能在一个线程中执行ui界面的刷新和网络请求和逻辑处理,需要一个一个的执行,不能并发执行。否则会造成死锁导致程序崩溃,执行速度慢效率差

多线程:​

可以通过主线程开辟多个子线程,多个线程都是可以独立执行的。所以可以并发执行。同时在执行效率上高,线程也安全。也不会因为一条线程的崩溃,而影响其他线程。

-(void)start;
-(void)main;

@property (readonly, getter=isCancelled) BOOL cancelled;
-(void)cancel;

@property (readonly, getter=isExecuting) BOOL executing;
@property (readonly, getter=isFinished) BOOL finished;
@property (readonly, getter=isConcurrent) BOOL concurrent; // To be deprecated; use and override ‘asynchronous’ below
@property (readonly, getter=isAsynchronous) BOOL asynchronous NS_AVAILABLE(10_8, 7_0);
@property (readonly, getter=isReady) BOOL ready;

-(void)addDependency:(NSOperation *)op;
-(void)removeDependency:(NSOperation *)op;

@property (readonly, copy) NSArray *dependencies;

typedef NS_ENUM(NSInteger, NSOperationQueuePriority) {
NSOperationQueuePriorityVeryLow = -8L,
NSOperationQueuePriorityLow = -4L,
NSOperationQueuePriorityNormal = 0,
NSOperationQueuePriorityHigh = 4,
NSOperationQueuePriorityVeryHigh = 8
};

@property NSOperationQueuePriority queuePriority;

@property (copy) void (^completionBlock)(void) NS_AVAILABLE(10_6, 4_0);

-(void)waitUntilFinished NS_AVAILABLE(10_6, 4_0);

@property double threadPriority NS_DEPRECATED(10_6, 10_10, 4_0, 8_0);

@property NSQualityOfService qualityOfService NS_AVAILABLE(10_10, 8_0);

@property (copy) NSString *name NS_AVAILABLE(10_10, 8_0);

一、NSOperation简介

和GCD一样,NSOperation也是苹果提供给我们的一套多线程解决方案。实际上它也是基于GCD开发的,但是比GCD拥有更强的可控性和代码可读性。

与 GCD 不同,操作队列不循序先进先出的次序。以下是操作队列与调度队列的不同之处:

不遵循 FIFO 次序:在操作队列中,你可以为操作设定执行优先级,并添加操作间的依赖关系。也就是说,你可以定义一些操作只在另一些操作完成之后才能被执行。这也是他们不遵循先进先出原则的原因。

默认情况下,操作队列并发运行:尽管不能将其类型改为串行队列,你仍能使用操作间的依赖关系指定任务的执行顺序。

操作队列是 NSOperationQueue 类的实例,其任务则封装在 NSOperation 的实例中。

NSOperation 是抽象类,因此无法直接使用。所以,你只能使用 NSOperation 的子类。在 iOS SDK 中,提供了两个 NSOperation 的具体子类。这些类可以直接使用,不过,你也可以自行创建 NSOperation 的子类来执行操作。我们可以直接使用的两个类为:

NSBlockOperation —— 使用此类可创建带有一个或多个块的操作。操作本身可包含多个块,而且只有当所有块都执行完毕时,该操作才算完成。
NSInvocationOperation —— 使用此类创建的操作能够针对特定对象唤起选择器。

1.简单说明

NSOperation的作⽤:配合使用NSOperation和NSOperationQueue也能实现多线程编程

NSOperation和NSOperationQueue实现多线程的具体步骤:

(1)先将需要执行的操作封装到一个NSOperation对象中

(2)然后将NSOperation对象添加到NSOperationQueue中

(3)系统会⾃动将NSOperationQueue中的NSOperation取出来

(4)将取出的NSOperation封装的操作放到⼀条新线程中执⾏

2.NSOperation的子类

NSOperation是个抽象类,并不具备封装操作的能力,必须使⽤它的子类

使用NSOperation⼦类的方式有3种:

(1)NSInvocationOperation

(2)NSBlockOperation

(3)自定义子类继承NSOperation,实现内部相应的⽅法

//创建操作对象,封装要执行的任务
//NSInvocationOperation 封装操作
NSInvocationOperation *operation=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test) object:nil];

//执行操作
[operation start];

这里要注意:默认情况下,调用了start方法后并不会开一条新线程去执行操作,而是在当前线程同步执行操作。只有将operation放到一个NSOperationQueue中,才会异步执行操作。

注意:操作对象默认在主线程中执行,只有添加到队列中才会开启新的线程。即默认情况下,如果操作没有放到队列中queue中,都是同步执行。只有将NSOperation放到一个NSOperationQueue中,才会异步执行操作 。

只要NSBlockOperation封装的操作数 > 1,就会异步执行操作 。

//创建NSInvocationOperation对象,封装操作
NSInvocationOperation *operation1=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test1) object:nil];
NSInvocationOperation *operation2=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test2) object:nil];
//创建对象,封装操作
NSBlockOperation *operation3=[NSBlockOperation blockOperationWithBlock:^{
NSLog(@”NSBlockOperation3–1—-%@”,[NSThread currentThread]);
}];
[operation3 addExecutionBlock:^{
NSLog(@”NSBlockOperation3–2—-%@”,[NSThread currentThread]);
}];

//创建NSOperationQueueNSOperationQueue * queue=[[NSOperationQueue alloc]init];//把操作添加到队列中[queue addOperation:operation1];[queue addOperation:operation2];[queue addOperation:operation3];

输出:
2017-03-01 13:38:38.585 Test[72718:4387436] NSInvocationOperation–test2–{number = 4, name = (null)}
2017-03-01 13:38:38.585 Test[72718:4387437] NSInvocationOperation–test1–{number = 3, name = (null)}
2017-03-01 13:38:38.585 Test[72718:4387461] NSBlockOperation3–2—-{number = 5, name = (null)}
2017-03-01 13:38:38.585 Test[72718:4387440] NSBlockOperation3–1—-{number = 6, name = (null)}

注意:系统自动将NSOperationqueue中的NSOperation对象取出,将其封装的操作放到一条新的线程中执行。上面的代码示例中,一共有四个任务,operation1和operation2分别有一个任务,operation3有两个任务。一共四个任务,开启了四条线程。通过任务执行的时间全部都是273可以看出,这些任务是并行执行的。

提示:队列的取出是有顺序的,与打印结果并不矛盾。这就好比,选手A,BC虽然起跑的顺序是先A,后B,然后C,但是到达终点的顺序却不一定是A,B在前,C在后。

GCD是基于c的底层api,NSOperation属于object-c类。iOS 首先引入的是NSOperation,IOS4之后引入了GCD和NSOperationQueue并且其内部是用gcd实现的。

相对于GCD:
1,NSOperation拥有更多的函数可用,具体查看api。
2,在NSOperationQueue中,可以建立各个NSOperation之间的依赖关系。
3,有kvo,可以监测operation是否正在执行(isExecuted)、是否结束(isFinished),是否取消(isCanceld)。
4,NSOperationQueue可以方便的管理并发、NSOperation之间的优先级。
GCD主要与block结合使用。代码简洁高效。
GCD也可以实现复杂的多线程应用,主要是建立个个线程时间的依赖关系这类的情况,但是需要自己实现相比NSOperation要复杂。
具体使用哪个,依需求而定。 从个人使用的感觉来看,比较合适的用法是:除了依赖关系尽量使用GCD,因为苹果专门为GCD做了性能上面的优化。

http://www.jianshu.com/p/0c241a4918bf

http://www.cnblogs.com/mjios/archive/2013/04/19/3029765.html

http://www.cocoachina.com/game/20151201/14517.html

http://mobile.51cto.com/iphone-386596.htm

http://blog.sina.com.cn/s/blog_1365d57560102wtfz.html

0 0
原创粉丝点击