iOS多線程總結(jié)2-NSOperation

iOS多線程總結(jié)2-NSOperation

歡迎交流,歡迎指出錯誤

推薦雷純峰大大的一篇文章《iOS 并發(fā)編程之 Operation Queues

簡介

NSOperation是基于GCD封裝的,是一套面向?qū)ο蟮亩嗑€程API。

一、NSOperationQueue

NSOperationQueue是操作隊列,簡單介紹一下它的一些方法屬性。

  1. maxConcurrentOperationCount

The default maximum number of operations is determined dynamically by the NSOperationQueue object based on current system conditions.

這句話的意思是maxConcurrentOperationCount缺省值是由當(dāng)前系統(tǒng)動態(tài)決定。

當(dāng)?shù)扔?時,操作隊列為串行隊列。

  1. qualityOfService

服務(wù)的優(yōu)先級

Used to indicate the nature and importance of work to the system. Work with higher quality of service classes receive more resources than work with lower quality of service classes whenever there is resource contention.

這句話的意思是qualityOfService的級別越高,當(dāng)前隊列的優(yōu)先級就越高,可以獲得更多的系統(tǒng)資源。

typedef NS_ENUM(NSInteger, NSQualityOfService) {
    NSQualityOfServiceUserInteractive = 0x21,
    NSQualityOfServiceUserInitiated = 0x19,
    NSQualityOfServiceUtility = 0x11,
    NSQualityOfServiceBackground = 0x09,

    /* Default QoS indicates the absence of QoS information.  Whenever possible QoS information will be inferred from other sources.  If such inference is not possible, a QoS between UserInitiated and Utility will be used. */
    NSQualityOfServiceDefault = -1
} NS_ENUM_AVAILABLE(10_10, 8_0);

  • NSQualityOfServiceUserInteractive:主要用于提供交互UI的交互;
  • NSQualityOfServiceUserInitiated:主要用于需要立即返回的任務(wù);
  • NSQualityOfServiceUtility:用于不需要立即返回的任務(wù);
  • NSQualityOfServiceBackground:用于不緊急的后臺任務(wù);
  • NSQualityOfServiceDefault:當(dāng)沒有設(shè)置優(yōu)先級的時候,線程默認(rèn)優(yōu)先級,通常是根據(jù)發(fā)起者來確定的,如果沒有這方面的信息,那么Default的優(yōu)先級就會在UserInitiatedUtility之間;

NSOperation

具體使用就不寫了,推薦文章很詳細(xì)了。寫一下使用時要注意的一個點。

queuePriority的設(shè)置

操作Operation在操作隊列OperationQueue中的優(yōu)先級

優(yōu)先級最高并不一定就是第一個被隊列派發(fā)執(zhí)行,這和隊列的最大并發(fā)數(shù)有關(guān)系。

看下面這段代碼:

- (void)queueTest {
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue setMaxConcurrentOperationCount:5];
    NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(test:) object:@"invocation test1"];
    [operation1 setQueuePriority:NSOperationQueuePriorityLow];
    
    NSInvocationOperation *operation2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(test:) object:@"invocation test2"];
    [operation2 setQueuePriority:NSOperationQueuePriorityLow];

    NSInvocationOperation *operation3 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(test:) object:@"invocation test3"];
    [operation3 setQueuePriority:NSOperationQueuePriorityVeryHigh];

    NSInvocationOperation *operation4 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(test:) object:@"invocation test4"];
    [operation4 setQueuePriority:NSOperationQueuePriorityLow];
    NSInvocationOperation *operation5 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(test:) object:@"invocation test5"];
    [operation5 setQueuePriority:NSOperationQueuePriorityLow];
    NSInvocationOperation *operation6 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(test:) object:@"invocation test6"];
    [operation6 setQueuePriority:NSOperationQueuePriorityLow];
    NSInvocationOperation *operation7 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(test:) object:@"invocation test7"];
    [operation7 setQueuePriority:NSOperationQueuePriorityLow];
    NSInvocationOperation *operation8 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(test:) object:@"invocation test8"];
    [operation8 setQueuePriority:NSOperationQueuePriorityLow];
    [queue addOperations:@[operation1, operation2, operation4, operation5, operation6, operation7, operation8,operation3] waitUntilFinished:YES];
}

- (void)test:(NSString *)obj {
    NSLog(@"%@", [NSThread currentThread]);
    NSLog(@"%@", obj);
}
2017-09-20 15:16:32.818 NSOperationDemo[27381:1869650] <NSThread: 0x60000007d680>{number = 6, name = (null)}
2017-09-20 15:16:32.818 NSOperationDemo[27381:1869634] <NSThread: 0x60000007d580>{number = 5, name = (null)}
2017-09-20 15:16:32.818 NSOperationDemo[27381:1869633] <NSThread: 0x6080000789c0>{number = 4, name = (null)}
2017-09-20 15:16:32.818 NSOperationDemo[27381:1869649] <NSThread: 0x60000007d500>{number = 3, name = (null)}
2017-09-20 15:16:32.819 NSOperationDemo[27381:1869634] invocation test2
2017-09-20 15:16:32.818 NSOperationDemo[27381:1869650] invocation test4
2017-09-20 15:16:32.819 NSOperationDemo[27381:1869633] invocation test1
2017-09-20 15:16:32.819 NSOperationDemo[27381:1869636] <NSThread: 0x60000007d5c0>{number = 7, name = (null)}
2017-09-20 15:16:32.819 NSOperationDemo[27381:1869649] invocation test3
2017-09-20 15:16:32.820 NSOperationDemo[27381:1869650] <NSThread: 0x60000007d680>{number = 6, name = (null)}
2017-09-20 15:16:32.820 NSOperationDemo[27381:1869634] <NSThread: 0x60000007d580>{number = 5, name = (null)}
2017-09-20 15:16:32.820 NSOperationDemo[27381:1869636] invocation test5
2017-09-20 15:16:32.820 NSOperationDemo[27381:1869633] <NSThread: 0x6080000789c0>{number = 4, name = (null)}
2017-09-20 15:16:32.820 NSOperationDemo[27381:1869650] invocation test6
2017-09-20 15:16:32.820 NSOperationDemo[27381:1869634] invocation test7
2017-09-20 15:16:32.866 NSOperationDemo[27381:1869633] invocation test8

當(dāng)并發(fā)數(shù)為5時,通過log打印,我們可以發(fā)現(xiàn)優(yōu)先級最高的operation3并不是第一個派發(fā)的。我們將maxConcurrentOperationCount改為2,再看一下log:

2017-09-20 15:21:59.866 NSOperationDemo[27497:1879269] <NSThread: 0x60000007bb80>{number = 3, name = (null)}
2017-09-20 15:21:59.866 NSOperationDemo[27497:1879268] <NSThread: 0x600000262d00>{number = 4, name = (null)}
2017-09-20 15:21:59.867 NSOperationDemo[27497:1879269] invocation test3
2017-09-20 15:21:59.867 NSOperationDemo[27497:1879268] invocation test1
2017-09-20 15:21:59.868 NSOperationDemo[27497:1879269] <NSThread: 0x60000007bb80>{number = 3, name = (null)}
2017-09-20 15:21:59.869 NSOperationDemo[27497:1879268] <NSThread: 0x600000262d00>{number = 4, name = (null)}
2017-09-20 15:21:59.869 NSOperationDemo[27497:1879269] invocation test2
2017-09-20 15:21:59.869 NSOperationDemo[27497:1879268] invocation test4
2017-09-20 15:21:59.872 NSOperationDemo[27497:1879282] <NSThread: 0x600000262dc0>{number = 5, name = (null)}
2017-09-20 15:21:59.872 NSOperationDemo[27497:1879268] <NSThread: 0x600000262d00>{number = 4, name = (null)}
2017-09-20 15:21:59.873 NSOperationDemo[27497:1879268] invocation test6
2017-09-20 15:21:59.873 NSOperationDemo[27497:1879282] invocation test5
2017-09-20 15:21:59.874 NSOperationDemo[27497:1879268] <NSThread: 0x600000262d00>{number = 4, name = (null)}
2017-09-20 15:21:59.874 NSOperationDemo[27497:1879282] <NSThread: 0x600000262dc0>{number = 5, name = (null)}
2017-09-20 15:21:59.895 NSOperationDemo[27497:1879268] invocation test7
2017-09-20 15:21:59.895 NSOperationDemo[27497:1879282] invocation test8

我們發(fā)現(xiàn)operation3是一個被派發(fā)的了。然后我們將maxConcurrentOperationCount改為3,再看一下log:

2017-09-20 15:23:44.277 NSOperationDemo[27542:1883616] <NSThread: 0x608000071f00>{number = 5, name = (null)}
2017-09-20 15:23:44.277 NSOperationDemo[27542:1883614] <NSThread: 0x60000006ae00>{number = 3, name = (null)}
2017-09-20 15:23:44.277 NSOperationDemo[27542:1883630] <NSThread: 0x608000071e40>{number = 4, name = (null)}
2017-09-20 15:23:44.278 NSOperationDemo[27542:1883616] invocation test2
2017-09-20 15:23:44.278 NSOperationDemo[27542:1883630] invocation test3
2017-09-20 15:23:44.278 NSOperationDemo[27542:1883614] invocation test1
2017-09-20 15:23:44.279 NSOperationDemo[27542:1883631] <NSThread: 0x600000070640>{number = 6, name = (null)}
2017-09-20 15:23:44.279 NSOperationDemo[27542:1883630] <NSThread: 0x608000071e40>{number = 4, name = (null)}
2017-09-20 15:23:44.279 NSOperationDemo[27542:1883616] <NSThread: 0x608000071f00>{number = 5, name = (null)}
2017-09-20 15:23:44.279 NSOperationDemo[27542:1883631] invocation test4
2017-09-20 15:23:44.280 NSOperationDemo[27542:1883630] invocation test5
2017-09-20 15:23:44.280 NSOperationDemo[27542:1883616] invocation test6
2017-09-20 15:23:44.280 NSOperationDemo[27542:1883631] <NSThread: 0x600000070640>{number = 6, name = (null)}
2017-09-20 15:23:44.280 NSOperationDemo[27542:1883614] <NSThread: 0x60000006ae00>{number = 3, name = (null)}
2017-09-20 15:23:44.317 NSOperationDemo[27542:1883631] invocation test7
2017-09-20 15:23:44.317 NSOperationDemo[27542:1883614] invocation test8

我們發(fā)現(xiàn)operation3又不是第一個被派發(fā)的了。

總結(jié):優(yōu)先級高低并不能決定執(zhí)行順序,他所決定的是被操作隊列的派發(fā)的順序,假如操作隊列的并發(fā)數(shù)是2,那么操作隊列第一次派發(fā)的2個任務(wù)中,一定有優(yōu)先級最高的任務(wù),至于在本次派發(fā),該任務(wù)第幾個被執(zhí)行,則是不確定的。

三、NSBlockOperation

推薦文章講的很好了,不寫了。

四、自定義NSOperation子類

推薦文章講的很好了,不寫了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容