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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章