【iOS】多線程NSOperation

來源:互聯網
上載者:User

標籤:多線程   nsoperation   gcd   並發   nsoperation queue   

NSOperation是蘋果封裝的一套多線程的東西,不像GCD是純C語言的,這個是OC的。但相比較之下GCD會更快一些,但本質上NSOPeration是多GDC的封裝。

一、NSOperation與GCD的比較

GCD是基於c的底層api,NSOperation屬於object-c類。ios首先引入的是NSOperation,IOS4之後引入了GCD和NSOperationQueue並且其內部是用gcd實現的。

GCD優點:GCD主要與block結合使用。代碼簡潔高效。執行效率稍微高點。

NSOperation相對於GCD
1,NSOperation擁有更多的函數可用,具體查看api。NSOperationQueue 是在GCD基礎上實現的,只不過是GCD更高一層的抽象
2,在NSOperationQueue中,可以建立各個NSOperation之間的依賴關係
3,NSOperationQueue支援KVO。可以監測operation是否正在執行(isExecuted)、是否結束(isFinished),是否取消(isCanceld)
4,GCD 只支援FIFO 的隊列,而NSOperationQueue可以調整隊列的執行順序(通過調整權重)。NSOperationQueue可以方便的管理並發、NSOperation之間的優先順序。

使用NSOperation的情況:各個操作之間有依賴關係、操作需要取消暫停、並發管理、控制操作之間優先順序,限制同時能執行的線程數量.讓線程在某時刻停止/繼續等。

使用GCD的情況:一般的需求很簡單的多線程操作,用GCD都可以了,簡單高效。

從編程原則來說,一般我們需要儘可能的使用高等級、封裝完美的API,在必須時才使用底層API。
當需求簡單,簡潔的GCD或許是個更好的選擇,而Operation queue 為我們提供能更多的選擇。


二、NSOperation的簡單操作

?NSOperation(操作)配NSoperationQueue(隊列)來實現多線程.?沒有像GCD一樣串列並行什麼的, 直接拿來就能用.

?操作依賴:NSOperation可以通過設定依賴來保證執行順序.某一個操作的執行, 必須等待另一個操作完成才會繼續執行.

使用:[op1 addDependency:op2]  依賴關係可以跨隊列指定的.(不能弄成循環相依性)

?可以指定隊列的優先順序。


使用NSOperation的方法(3者是等價的 ):(注意NSOperation是抽象類別, 必須使用他的子類才能實現)
?方法1、用NSOperation的子類NSInvocationOperation來建立操作. ?方法2、用NSOperation的子類NSBlockOperation來建立操作. (與前者效果一樣) ?方法3、直接弄個隊列(可以是主隊列,先跑起來),再addOperationWithBlock更加簡便. ?方法4、直接自訂NSOperation,實現相應的方法。

實現NSOperation的方法,以及掛起、暫停,設定最大並發數,設定依賴關係等
@interface XNViewController ()/** NSOperation操作隊列 */@property (nonatomic, strong) NSOperationQueue *queue;@end@implementation XNViewController// 將操作添加到隊列即可- (NSOperationQueue *)queue{    if (!_queue) _queue = [[NSOperationQueue alloc] init];    return _queue;}/** ============================= 暫停掛起 ============================= *//** 暫停操作 */- (IBAction)pause{    // 1. 判斷隊列中是否有操作    if (self.queue.operationCount == 0) {        NSLog(@"沒有操作");        return;    }        // 2. 如果沒有被掛起(正在執行),才需要暫停    // 只會掛起當前隊列中還沒有被調度(沒有被安排到線程上工作的操作)才會被掛起    if (!self.queue.isSuspended) {        NSLog(@"暫停");        [self.queue setSuspended:YES];    } else {        NSLog(@"已經暫停");    }}/** 繼續操作 */- (IBAction)resume{    // 1. 判斷隊列中是否有操作    if (self.queue.operationCount == 0) {        NSLog(@"沒有操作");        return;    }        // 2. 如果有被擱置動作,才需要繼續(恢複)    if (self.queue.isSuspended) {        NSLog(@"繼續");        [self.queue setSuspended:NO];    } else {        NSLog(@"正在執行");    }}/** ========================NSOperation指定操作之間的依賴關係========================*/- (void)opDemo6{    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{        NSLog(@"正在下載蒼老師全集 。。。 %@", [NSThread currentThread]);    }];        NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{        NSLog(@"正在解壓縮蒼老師全集。。。 %@", [NSThread currentThread]);    }];        NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{        NSLog(@"正在儲存到磁碟 。。。 %@", [NSThread currentThread]);    }];        NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{        NSLog(@"下載完成 。 %@", [NSThread currentThread]);    }];        // 指定操作之間的”依賴“關係,某一個操作的執行,必須等待另一個操作完成才會開始    // 依賴關係是可以跨隊列指定的    [op2 addDependency:op1];    [op3 addDependency:op2];    [op4 addDependency:op3];    // *** 添加依賴的時候,注意不要出現循環相依性//    [op3 addDependency:op4];        [self.queue addOperation:op1];    [self.queue addOperation:op2];    [self.queue addOperation:op3];    // 主隊列更新UI    [[NSOperationQueue mainQueue] addOperation:op4];}/** ==================================設定最大並發數==================================== */- (void)opDemo5{    // 設定隊列的最大並發數,隊列是負責調度操作的    /**     最大並發數的應用情境:          1> 使用者在使用3G的時候          限制線程的數量,省電,省流量(省錢)     2> 使用者使用WIFI的時候(區域網路) 增加線程數量,提高使用者的體驗          maxConcurrentOperationCount 如果== 1,類似於串列隊列非同步方法呼叫     */    self.queue.maxConcurrentOperationCount = 1;        for (int i = 0; i < 10; i++) {        [self.queue addOperationWithBlock:^{                        NSLog(@"正在下載 %@ %d", [NSThread currentThread], i);        }];    }}/**  ============================= Block操作,添加執行塊 =============================  */- (void)opDemo4{    // 執行個體化block操作    NSBlockOperation *op = [[NSBlockOperation alloc] init];        // 設定最大並發(操作)數,不會限制執行塊!    self.queue.maxConcurrentOperationCount = 2;        // 添加執行塊    [op addExecutionBlock:^{        NSLog(@"下載蒼老師全集1 %@", [NSThread currentThread]);    }];        // 繼續添加塊    [op addExecutionBlock:^{        NSLog(@"下載蒼老師全集2 %@", [NSThread currentThread]);    }];        // 繼續添加塊    [op addExecutionBlock:^{        NSLog(@"下載蒼老師全集3 %@", [NSThread currentThread]);    }];        // 繼續添加塊    [op addExecutionBlock:^{        NSLog(@"下載蒼老師全集4 %@", [NSThread currentThread]);    }];        // 繼續添加塊    [op addExecutionBlock:^{        NSLog(@"下載蒼老師全集5 %@", [NSThread currentThread]);    }];        // 啟動操作,在主線程執行    // 如果執行塊的數量超過1,就會自動進入其他線程執行(非同步)    // 具體開啟線程的數量,由系統決定    // 執行塊的調度與操作的調度非常像//    [op start];    [self.queue addOperation:op];}/** ============================= 直接添加塊操作 ============================= */- (void)opDemo3{    // 只要將操作添加到隊列就會立即被調度(執行)    for (int i = 0; i < 10; i++) {        [self.queue addOperationWithBlock:^{            NSLog(@"下載開始 %@ - %@", [NSThread currentThread], @(i));        }];    }        // 向主隊列中添加操作    [[NSOperationQueue mainQueue] addOperationWithBlock:^{        NSLog(@"下載開始 %@ - %@", [NSThread currentThread], nil);    }];}/**============================= NSBlockOperation =============================*/- (void)opDemo2{    for (int i = 0; i < 10; i++) {        // 指定一個塊操作        NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{            NSLog(@"下載開始 %@ - %@", [NSThread currentThread], @(i));        }];                // 將塊操作添加到隊列. 新開線程        [self.queue addOperation:op1];    }}/** =============================NSInvocationOperation============================= */- (void)opDemo1{    for (int i = 0; i < 10; i++) {        NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download:) object:@(i)];                // 如果直接啟動,會在主線程執行        //    [op1 start];        // 添加到隊列,就會建立線程,非同步執行        [self.queue addOperation:op1];    }}- (void)download:(id)obj{    NSLog(@"下載開始 %@ - %@", [NSThread currentThread], obj);}@end

自訂NSOperation:1、繼承NSOperation2、重新main方法
@interface XNMyOperation : NSOperation@end//============================上為.h標頭檔,下為.m檔案=============================@implementation XNMyOperation// 只要重寫main就可以了- (void)main{    // 自訂動作,一定要自己添加自動釋放池    @autoreleasepool {        //。。。。。。。。。。。    }}@end

參考:

http://jianshu.io/p/d09e2638eb27

http://blog.csdn.net/hufengvip/article/details/11806897

http://blog.csdn.net/vieri_ch/article/details/21937859

apple官方文檔


轉載請註明出處:http://blog.csdn.net/xn4545945  



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.