iOS多線程編程之二——NSOperation與NSOperationQueue

iOS多線程編程之二——NSOperation與NSOperationQueue

1、NSOperation解析

NSOperation是基於Object-C封裝的一套管理與執行線程操做的類。這個類是一個抽象類,一般狀況下,咱們會使用NSInvocationOperation和NSBlockOperation這兩個子類進行多線程的開發,固然咱們也能夠寫繼承於NSOperation的類,封裝咱們本身的操做類。編程

一、NSOperation抽象類中提供的邏輯方法

操做開始執行數組

- (void)start;

 

在子類中能夠重寫這個方法,實現執行的方法多線程

- (void)main;

 

取消執行異步

- (void)cancel;

 

獲取當操做狀態的幾個屬性async

@property (readonly, getter=isCancelled) BOOL cancelled;//當前操做是否取消執行
@property (readonly, getter=isExecuting) BOOL executing;//當前操做是否正在執行
@property (readonly, getter=isFinished) BOOL finished;//當前操做是否執行結束
@property (readonly, getter=isAsynchronous) BOOL asynchronous;//當前操做是否在異步線程中
@property (readonly, getter=isReady) BOOL ready;//當前操做是否已經準備好

 

阻塞當前線程直到操做完成學習

- (void)waitUntilFinished;

 

設置在操做隊列中的優先級spa

@property NSOperationQueuePriority queuePriority;

其中NSOperationQueuePriority的枚舉以下:線程

typedef NS_ENUM(NSInteger, NSOperationQueuePriority) {
    NSOperationQueuePriorityVeryLow = -8L,//優先級很低
    NSOperationQueuePriorityLow = -4L,//優先級低
    NSOperationQueuePriorityNormal = 0,//優先級普通
    NSOperationQueuePriorityHigh = 4,//優先級高
    NSOperationQueuePriorityVeryHigh = 8//優先級很是高
};


設置操做完成後的回調blockcode

@property (copy) void (^completionBlock)(void);

 

設置操做的優先級orm

@property double threadPriority;

 

設置操做的名稱

@property (copy) NSString *name;

二、帶block的操做類實例——NSBlockOperation

NSBlockOperation是NSOperation的一個子類,其能夠異步的執行多個block,當全部的block都完成時,這個操做纔算完成。

初始化方法:

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

 

在操做中添加block

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

 

添加進去的block的數組

@property (readonly, copy) NSArray *executionBlocks;

示例以下:

NSBlockOperation * opera = [NSBlockOperation blockOperationWithBlock:^{
        for (int i=0; i<10; i++) {
            NSLog(@"%@=%d",[NSThread currentThread],i);
        }
    }];
    [opera addExecutionBlock:^{
        for (int i=0; i<10; i++) {
            NSLog(@"%@=%d",[NSThread currentThread],i);
        }
    }];
    [opera start];

打印狀況以下,能夠看出,兩個block塊的執行是異步的:

三、使用NSInvocationOperation調用方法

根據選擇器建立一個對象

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

 

經過Invocation建立一個對象

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

 

這個類執行的操做是與調用它的線程同步的,示例以下:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.  
    NSInvocationOperation * operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(log) object:nil];
    [operation start];
        for (int i=0; i<10; i++) {
        NSLog(@"%@=%d",[NSThread currentThread],i);
        }  
}


-(void)log{
    for (int i=0; i<100; i++) {
        NSLog(@"%@=%d",[NSThread currentThread],i);
    }
}

經過打印結果能夠看出其執行的同步性。

2、操做之間的依賴關係

依賴關係和優先級的做用很像,卻也不一樣。若是一個操做A依賴於另外一個操做B,那麼只有當B操做完成後,A操做纔會執行。操做添加依賴的

添加一個依賴:

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

 

刪除一個依賴

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

原則上說,一個操做對象的依賴能夠添加多個,而且當全部依賴都執行完成後纔會執行這個操做。

 

3、NSOperationQueue操做隊列

NSOperationQueue是操做隊列類,經過上面的介紹,咱們已經能夠理解操做,而且操做默認的執行方式是串行的,儘管NSBlockOperation中的block塊間是並行執行的,但其和外部操做依然是串行的。若是將操做放入操做隊列中,則默認爲並行執行的。

示例以下:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    NSOperationQueue * queue = [[NSOperationQueue alloc]init];
    NSInvocationOperation * op1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(log) object:nil];
    [queue addOperation:op1];
    for (int i=0; i<10; i++) {
        NSLog(@"%@=%d",[NSThread currentThread],i);
    }
}

-(void)log{
    for (int i=0; i<10; i++) {
        NSLog(@"%@=%d",[NSThread currentThread],i);
    }
}

打印信息以下:

能夠看出來,隊列的操做是在一個新的線程中執行的,而且操做隊列之中的操做也都是異步執行的。

 

在操做隊列中添加一個操做任務:

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

 

在隊列中插入一組操做任務,後面的參數設置是否隊列中得任務都執行完成後再執行這一組操做:

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

 

在隊列中添加一個block操做

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

 

獲取操做隊列中的全部操做的數組

@property (readonly, copy) NSArray *operations;

 

獲取操做隊列中操做的個數

@property (readonly) NSUInteger operationCount;

 

設置隊列最大並行操做數量

@property NSInteger maxConcurrentOperationCount;

 

設置是否暫停隊列任務執行

@property (getter=isSuspended) BOOL suspended;

 

設置隊列名字

@property (copy) NSString *name;

 

設置隊列的優先級別(iOS8後支持)

@property NSQualityOfService qualityOfService;

 

取消隊列中全部操做任務

- (void)cancelAllOperations;

 

阻塞當前線程,直到隊列中全部任務完成

- (void)waitUntilAllOperationsAreFinished;

 

獲取當前執行的隊列

+ (NSOperationQueue *)currentQueue;

 

獲取主線程中的操做隊列

+ (NSOperationQueue *)mainQueue;

 

4、隊列中操做的執行順序法則

一、決定於依賴關係,只有當這個操做的依賴所有執行完成後,它纔會被執行。

二、影響於優先級,優先級高的會先執行。

 

若有疏漏 歡迎指正

學習使用 歡迎轉載

專一技術,熱愛生活,交流技術,也作朋友。

——琿少 QQ羣:203317592

相關文章
相關標籤/搜索