天天看點

iOS多線程之NSOperation

iOS多線程之NSOperation

在GCD的基礎上包裝而來,相較于GCD而言,可控性更強,并且加入了操作依賴。

NSOperation是一個抽象的基類,不可直接使用,隻能使用其子類,為子類提供了線程的建立狀态,優先級,依賴和取消等操作。系統已經給我們封裝了NSBlockOperation和NSInvocationOperation這兩個實體類,供我們使用,當然我們也可以自定義NSOperation的子類,需要重載-(void)main這個方法。

NSOperation可以自己獨立執行(直接調用[operation start]), 也可以放到NSOperationQueue裡面執行。NSOperation 在預設情況下是非并發的,當你将此操作放到線程執行,他會阻塞該線程,直到執行完成。NSOperation也可以直接實作并發執行。但需要重寫isConcurrent  isExecuting  isFinished 以及start函數,讓isConcurrent 傳回YES,再開始結束的時候手動設定 isExecuting  isFinished的狀态;如果将NSOperation加入NSOperationQueue隊列中去執行,那麼我們隻需去管理NSOperationQueue隊列即可,它基本上是并發執行。下面先了解系統提供給我們的NSOperation NSBlockOperation NSInvocationOperation NSOperationQueue的一些屬性與方法。

NSOperation方法屬性

- (void)start;//開始執行操作

- (void)main;//操作入口函數

@property (readonly, getter=isCancelled) BOOL cancelled;//操作狀态,表示操作是否取消

- (void)cancel;//取消操作,将cancelled狀态置成YES,而非取消操作

@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;// 判斷操作準備完成

- (void)addDependency:(NSOperation *)op;//添加依賴操作

- (void)removeDependency:(NSOperation *)op;//移除依賴操作

@property (readonly, copy) NSArray<NSOperation *> *dependencies;//操作依賴組

typedef NS_ENUM(NSInteger, NSOperationQueuePriority) {//操作隊列優先級

NSOperationQueuePriorityVeryLow = -8L,//低

NSOperationQueuePriorityLow = -4L,//較低

NSOperationQueuePriorityNormal = 0,//正常

NSOperationQueuePriorityHigh = 4,//較高

NSOperationQueuePriorityVeryHigh = 8//高

};

@property NSOperationQueuePriority queuePriority;//操作隊列優先級

@property (nullable, copy) void (^completionBlock)(void) ;//操作完成後執行函數

- (void)waitUntilFinished ;//操作對象等待知道某個任務結束

@property double threadPriority ;//線程優先級

@property NSQualityOfService qualityOfService ;//操作對象優先級

@property (nullable, copy) NSString *name ;//操作對象名稱

+ (instancetype)blockOperationWithBlock:(void (^)(void))block;//初始化操作對象

- (void)addExecutionBlock:(void (^)(void))block;//添加操作任務

@property (readonly, copy) NSArray<void (^)(void)> *executionBlocks;//執行的任務集數組

- (nullable instancetype)initWithTarget:(id)target selector:(SEL)sel object:(nullable id)arg;//初始化操作對象,封裝要執行的任務

- (instancetype)initWithInvocation:(NSInvocation *)inv ;初始化操作對象,封裝要執行的任務

@property (readonly, retain) NSInvocation *invocation;//要執行的任務

@property (nullable, readonly, retain) id result;//操作結果

static const NSInteger NSOperationQueueDefaultMaxConcurrentOperationCount = -1;//操作隊列預設最大并行操作數

- (void)addOperation:(NSOperation *)op;//給操作隊列添加操作

- (void)addOperations:(NSArray<NSOperation *> *)ops waitUntilFinished:(BOOL)wait ;//給操作隊列添加操作

- (void)addOperationWithBlock:(void (^)(void))block;//給操作隊列以塊的形式添加操作

@property (readonly, copy) NSArray<__kindof NSOperation *> *operations;//操作隊列操作集(所有操作)

@property (readonly) NSUInteger operationCount;//操作隊列操作個數(所有操作總數目)

@property NSInteger maxConcurrentOperationCount;//操作隊列并發執行操作個數最大個數,如果設為1,那麼就成了串行操作了。

@property (getter=isSuspended) BOOL suspended;//操作隊列是否挂起

@property (nullable, copy) NSString *name;//操作隊列名稱

@property NSQualityOfService qualityOfService;//操作隊列優先級

@property (nullable, assign ) dispatch_queue_t underlyingQueue;//潛在的隊列

- (void)cancelAllOperations;//取消操作隊列中的所有操作

- (void)waitUntilAllOperationsAreFinished;//等待直到所有操作完成

NSOperation多線程示例

-( void )initMultiOperation

{

   NSInvocationOperation *myInvocationOpt=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(myFunc:) object:@"invocation"];

  [myInvocationOpt setName:@"InvocationOperation"];

    [myInvocationOpt start];

  NSBlockOperation *myBlockOpt = [NSBlockOperation blockOperationWithBlock:^{

        NSLog(@"task:%@",[NSThread currentThread]);

    }];

[myInvocationOpt setName:@"BlockOperation"];

    [myOpt addExecutionBlock:^{

        NSLog(@"block:%@",[NSThread currentThread].name);

    }];

    [myOpt addExecutionBlock:^{

        NSLog(@"task-block:%@",[NSThread currentThread]);

    }];

    [myBlockOpt start];

  myOperation *myOpt=[[myOperation alloc]init];//自定義NSOperation子類,重寫main函數,當調用start函數後,自動開始從入口函數main執行操作

[myOpt setName:@"myOperation"];

    [myOpt start];

}

-(void)myFunc:(NSString *)str

{

    NSLog(@"task-invocation:%@----------%@",[NSThread currentThread],str);

}

NSOperationQueue隊列多線程示例

-(void)operationQueue

{

    NSOperationQueue *myOptQueue=[[NSOperationQueue alloc]init];

    [myOptQueue setName:@"hello"];

    [myOptQueue setMaxConcurrentOperationCount:3];

    NSBlockOperation *myBlock=[NSBlockOperation blockOperationWithBlock:^{

        NSLog(@"My First Task");

    }];

    [myBlock addExecutionBlock:^{

        NSLog(@"My Sencond Task");

    }];

    [myBlock addExecutionBlock:^{

        NSLog(@"My Third Task");

    }];

     NSInvocationOperation *myInvocation=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(myFunc:) :@"NSInvocationOperation"];

    [myInvocation setQueuePriority:NSOperationQueuePriorityVeryLow];//設定優先級

    [myBlock addDependency:myInvocation];//添加依賴,myBlock執行與myInvocation之後

    [myOptQueue addOperation:myInvocation];//給操作隊列添加myInvocation操作

     //[myInvocation cancel];設定myInvocation操作狀态cancelled為YES,如果該操作還未執行,就取消該操作,不再執行;在執行中,等待執行完成,設定标志完成

    [myOptQueue addOperation:myBlock]; //給操作隊列添加myBlock操作

    [myOptQueue addOperationWithBlock:^{ //給操作隊列添加塊操作

        NSLog(@"My Fourth Task");

    }];

    //[myOptQueue cancelAllOperations];//取消操作隊列中所有的操作

    [myOptQueue setSuspended:YES];//挂起本操作隊列

    if([myOptQueue isSuspended])

    {

        NSLog(@"setSuspended:YES");

        [myOptQueue setSuspended:NO];//恢複本操作隊列

    }

    myInvocation.completionBlock=^{ //myInvocation操作結束後調用

        NSLog(@"myInvocation over!!!");

    };

}