iOS 多线程编程之NSOperation

一、NSOperation简介

相对于前面所说的NSThread,NSOperation同样用于多线程,但是相比较而言,NSOperation是更高级别的类,它大大的简化了处理多线程的过程,但是NSOperation是一个抽象基类,如果需要使用它的话,必须使用它的字累,或者自定义子类继承NSOperation,实现内部响应的方法。在此之前稍稍补充几个术语。
异步:不用阻塞当前线程来等待处理完成,而是允许后续操作,直至其它线程将处理完成,并回调通知此线程,不需要占用额外线程。

同步:对在一个系统中所发生的事件之间进行协调,在时间上出现一致性与统一化

线程 :是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源

进程:是系统进行资源分配和调度的基本单位

并行:一组程序按独立异步的速度执行

并发:指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。

二、使用NSOperation实现多线程的具体步骤
1) 先将需要执行的操作封装到一个NSOperation对象中;
2) 两种方式调用NSOperation;
2.1) NSOperation调用start方法执行任务,但默认是同步的;
2.2)将NSOperation对象添加到NSOperationQueue中,系统会自动异步执行NSOperation中的操作;  
2.2.1)系统会自动将NSOperationQueue中的NSOperation取出来;
2.2.2)NSOperationQueue会开辟一条新线程,将取出的NSOperation封装的操作进行执行。

三、NSOperation的子类

1. NSInvocationOperation
2. NSBlockOperation
3. 自定义NSOperation子类

四、NSOperation相关操作

a.执行操作
NSOperation调用start方法即可开始执行操作,NSOperation对象默认按同步方式执行,也就是在调用start方法的那个线程中直接执行。NSOperation对象的isConcurrent方法会告诉我们这个操作相对于调用start方法的线程,是同步还是异步执行。isConcurrent方法默认返回NO,表示操作与调用线程同步执行。

[operation start];
b.取消操作
[operation cancel];
c.监听执行操作
operation.completionBlock = ^(){
        NSLog(@"%s",__func__);
    };
[operation setCompletionBlock:^{
        NSLog(@"%s",__func__);
    }];
五、NSOperation子类的使用

a.NSInvocationOperation

NSInvocationOperation是基于一个对象和selector来创建操作的。如果你已经有现有的方法来执行需要的任务,就可以使用这个类。

创建并执行的操作

NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil];
    [operation start];
    
    - (void)run
	{
    	NSLog(@"---%@---",[NSThread currentThread]);
	}

b.NSBlockOperation

NSBlockOperation能够并发地执行一个或多个block对象,所有相关的block都执行完之后,操作才算完成

// 创建NSBlockOperation对象
    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^(){
        NSLog(@"线程1=====%@", [NSThread currentThread]);
    }];
    // 通过addExecutionBlock方法添加block操作
    [operation addExecutionBlock:^{
        NSLog(@"线程2=====%@",[NSThread currentThread]);
    }];
    [operation addExecutionBlock:^{
        NSLog(@"线程3=====%@",[NSThread currentThread]);
    }];
    // 开始执行任务(这里还是同步执行)
    [operation start];

c.自定义NSOperation子类

如果NSInvocationOperation和NSBlockOperation都不能够满足需求,那么就只能自定义继承于NSOperation的子类了,继承NSOperation需要重写NSOperation的基本方法。

例子:

.h文件

@interface PPDownLoadOperation : NSOperation
	@property(nonatomic,copy)NSString *url;
	@property(nonatomic,weak)id delegate;

	@end


	@protocol PPDownLoadOperationDelegate <NSObject>

	- (void)didFishedDownLoadImage:(UIImage *)image;

	@end
.m文件
-(void)main
	{
    	@autoreleasepool {
        	if (self.isCancelled) {
            	return;
        	}
    
        	NSURL *url = [NSURL URLWithString:self.url];
        	NSData *data = [NSData dataWithContentsOfURL:url];    
        	if (self.isCancelled) {
            	url = nil;
            	data = nil;
            	return;
        	}
        
        	UIImage *imgae=[UIImage imageWithData:data];
        	if (self.isCancelled) {
            	imgae = nil;
            	return;
        	}
        	//图片下载完毕后,通知代理
        	if ([self.delegate respondsToSelector:@selector(didFishedDownLoadImage:)]) 
        	{
            	dispatch_async(dispatch_get_main_queue(), ^{//回到主线程,传递数据给代理对象
                	[self.delegate didFishedDownLoadImage:imgae];
            	});
        	}
    	}
 	}

发布了39 篇原创文章 · 获赞 6 · 访问量 4万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章