iOS-多線程--介紹NSOperration

来源:http://www.cnblogs.com/nxz-diy/archive/2016/04/08/5367596.html
-Advertisement-
Play Games

一個NSOperation對象就代表一個操作,對象相當於GCD中的block。 一、NSOperation的作用: 配合使用NSOperation和NSOperationQueue也能實現多線程。 二、NSOperation和NSOperationQueue實現多線程的步驟: 步驟1: 先將需要執行 ...


一個NSOperation對象就代表一個操作,對象相當於GCD中的block。

 

一、NSOperation的作用:

配合使用NSOperation和NSOperationQueue也能實現多線程。

 

二、NSOperation和NSOperationQueue實現多線程的步驟:

步驟1: 先將需要執行的操作封裝到一個NSOperation對象中;

步驟2: 系統會自動將NSOperationQueue中得NSOperation取出來;

步驟3: 將取出來的NSOperation封裝的操作放到一條線程中執行。

 

三、NSOperation的子類

NSOperation是個抽象類,並不具備封裝操作的能力,必須使用它的子類

 

四、使用NSOperation子類的方式有3種: 1> NSInvocationOperation 2> NSBlockOperation 3> 自定義子類繼承NSOperation,實現內部相應的方法   五、使用方式: 方式1:用NSInvocationOperation, 代碼如下: 重要級別:演示
 1 - (void)viewDidLoad
 2 {
 3     [super viewDidLoad];
 4     
 5     // 創建隊列
 6     NSOperationQueue *queue = [[NSOperationQueue alloc] init];
 7     
 8     // 創建操作
 9     NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil];
10     // operation直接調用start,是同步執行(在當前線程執行操作)
11 //    [operation start];
12     
13     // 添加操作到隊列中,會自動非同步執行 (如果不將operation加到隊列中,直接[operation start];執行的話,就相當於調用 [self download], 不是非同步執行,是在主線程執行的;添加到操作隊列中,會開啟一個新的線程,非同步執行)
14 
15     [queue addOperation:operation];
16 }
17 
18 - (void)download
19 {
20     NSLog(@"download-----%@", [NSThread currentThread]);
21 }

 

方式2. 用NSBlockOperation,代碼如下:

重要級別:瞭解(test1   test2 裡面的是瞭解)

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    [self test2];
}
- (void)test2
{
    NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"---下載圖片----11---%@", [NSThread currentThread]);
    }];
    
    [operation1 addExecutionBlock:^{
        NSLog(@"---下載圖片----12---%@", [NSThread currentThread]);
    }];
    
    NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"---下載圖片----2---%@", [NSThread currentThread]);
    }];
    
    NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"---下載圖片----3---%@", [NSThread currentThread]);
    }];
    
    NSBlockOperation *operation4 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"---下載圖片----4---%@", [NSThread currentThread]);
    }];
    
    // 1.創建隊列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 相當於GCD的全局併發隊列,下麵的四個操作都在新開啟的線程中非同步執行
    
    // 主隊列
    //  NSOperationQueue *queue = [NSOperationQueue mainQueue]; // 相當於GCD的主隊列,下麵的四個操作都在主隊列執行
    
    // 2.添加操作到隊列中(自動非同步執行)
    [queue addOperation:operation1];
    [queue addOperation:operation2];
    [queue addOperation:operation3];
    [queue addOperation:operation4];
}
- (void)test
{
    NSBlockOperation *operation = [[NSBlockOperation alloc] init];
    
    [operation addExecutionBlock:^{
        NSLog(@"---下載圖片----1---%@", [NSThread currentThread]);
    }];
    
    [operation addExecutionBlock:^{
        NSLog(@"---下載圖片----2---%@", [NSThread currentThread]);
    }];
    
    [operation addExecutionBlock:^{
        NSLog(@"---下載圖片----3---%@", [NSThread currentThread]);
    }];
    
    [operation start];
    
    // 任務數量 > 1,才會開始非同步執行(不然的話就是同步執行,在主線程做的)
}

 

## 下麵的要掌握 ##

- (void)viewDidLoad
{
    [super viewDidLoad];

}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue addOperationWithBlock:^{
        // 1.非同步下載圖片
        NSURL *url = [NSURL URLWithString:@"http://d.hiphotos.baidu.com/image/pic/item/37d3d539b6003af3290eaf5d362ac65c1038b652.jpg"];
        NSData *data = [NSData dataWithContentsOfURL:url];
        UIImage *image = [UIImage imageWithData:data];
        
        // 2.回到主線程,顯示圖片
//        [self performSelectorOnMainThread:<#(SEL)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>];
//        dispatch_async(dispatch_get_main_queue(), ^{
//            
//        });
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            self.imageView.image = image;
        }];
    }];
}

- (void)dependency
{
    /**
     假設有A、B、C三個操作,要求:
     1. 3個操作都非同步執行
     2. 操作C依賴於操作B
     3. 操作B依賴於操作A
     */
    
    // 1.創建一個隊列(非主隊列)
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    // 2.創建3個操作
    NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"A1---%@", [NSThread currentThread]);
    }];
    //    [operationA addExecutionBlock:^{
    //        NSLog(@"A2---%@", [NSThread currentThread]);
    //    }];
    //
    //    [operationA setCompletionBlock:^{
    //        NSLog(@"AAAAA---%@", [NSThread currentThread]);
    //    }];
    
    NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"B---%@", [NSThread currentThread]);
    }];
    NSBlockOperation *operationC = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"C---%@", [NSThread currentThread]);
    }];
    
    // 設置依賴
    [operationB addDependency:operationA];
    [operationC addDependency:operationB];
    
    // 3.添加操作到隊列中(自動非同步執行任務)
    [queue addOperation:operationC];
    [queue addOperation:operationA];
    [queue addOperation:operationB];
}

- (void)maxCount
{
    // 1.創建一個隊列(非主隊列,會創建新的線程)
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    // 2.設置最大併發(如果設置為3,則最多同時併發執行3個任務)
    queue.maxConcurrentOperationCount = 3; // 如果設置為1,那麼下麵的任務是在新線程中依次執行的。
    
    // 3.添加操作到隊列中(自動非同步執行任務,併發)
   // 下麵五個操作都非同步執行,如果有的操作要在方法裡面執行,可以用 操作5 這種形式去實現
.
   // 操作1
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"下載圖片1---%@", [NSThread currentThread]); }];
   // 操作2 NSBlockOperation
*operation2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"下載圖片2---%@", [NSThread currentThread]); }];
   // 操作3
NSBlockOperation
*operation3 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"下載圖片3---%@", [NSThread currentThread]); }];
   // 操作4
NSBlockOperation
*operation4 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"下載圖片4---%@", [NSThread currentThread]); }];
   // 操作5
NSInvocationOperation
*operation5 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil]; [queue addOperation:operation1]; [queue addOperation:operation2]; [queue addOperation:operation3]; [queue addOperation:operation4]; [queue addOperation:operation5]; [queue addOperationWithBlock:^{ NSLog(@"下載圖片5---%@", [NSThread currentThread]); }]; [queue addOperationWithBlock:^{ NSLog(@"下載圖片6---%@", [NSThread currentThread]); }]; [queue addOperationWithBlock:^{ NSLog(@"下載圖片7---%@", [NSThread currentThread]); }]; [queue addOperationWithBlock:^{ NSLog(@"下載圖片8---%@", [NSThread currentThread]); }]; [queue addOperationWithBlock:^{ NSLog(@"下載圖片9---%@", [NSThread currentThread]); }]; [queue cancelAllOperations]; }
- (void)download
{
  NSLog(@"download---%@", [NSThread currentThread]);
}
- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // [queue cancelAllOperations]; // 取消隊列中的所有任務(不可恢復) } - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { // [queue setSuspended:YES]; // 暫停隊列中的所有任務 } - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { // [queue setSuspended:NO]; // 恢復隊列中的所有任務 } - (void)baseUse { // 1.創建一個隊列(非主隊列) NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 2.添加操作到隊列中(自動非同步執行任務,併發) NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"下載圖片1---%@", [NSThread currentThread]); }]; NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"下載圖片2---%@", [NSThread currentThread]); }]; [queue addOperation:operation1]; [queue addOperation:operation2]; [queue addOperationWithBlock:^{ NSLog(@"下載圖片3---%@", [NSThread currentThread]); }]; // 3個操作併發執行 }

 

六、操作依賴:

1. NSOperation之間可以設置依賴來保證執行順序     比如一定要讓操作A執行完後,才能執行操作B,可以這麼寫:

    [operationB addDependency:operationA]; // 操作B依賴於操作A

 

2. 可以在不同queue的NSOperation之間創建依賴關係:   
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 今天開始記錄每天所學的重點,為了加深印象也為了今後的複習。 今天學習的重點是引用類型中Array類型,Array類型中的棧方法,隊列方法,重排序方法,操作方法,位置方法,迭代方法,歸併方法。這幾個方法我感覺尤為重要,因此記錄下來,以便忘記了可以回顧。 (一)棧方法 首先要知道的是棧是一種後進先出的數 ...
  • 一、事件編程 1、基本事件(以方法形式存在的) 基本語法: 原生Javascript代碼中的事件綁定方式: DOM對象.事件 = 事件的處理程式 jQuery代碼中的事件綁定方式: jQuery對象.事件(事件處理程式) 2、常用的事件列表 blur(fn) :當失去焦點時觸發 change(fn)... ...
  • 第一章 1、 郵箱地址的URL地址包括:mailto:+郵箱地址 2、 ../表示向上走一級,開頭直接使用/表示根目錄 第三章 1、 <header>: role = “banner”【 適用於頁面級的頁眉】 2、 <nav>標記導航: role = “navigation”不是必須的,提高可訪問性 ...
  • 4月7日學到的知識點: 一:<img src="1.png" alt="美女"/> alt是給圖片添加介紹,當圖片沒載入出來時,會直接顯示alt的值,在搜索引擎搜索時也可以讓搜索引擎更好的找到這張圖。 二:<a href="css2.ppt">標簽下載</a> 當href的值是一個文件名或者壓縮包時 ...
  • 性能優化一直是前端工作中十分重要的一環,都說從 10 到 1 容易,從 1 到 0 很難。而隨著前端技術的飛速發展,沒有什麼技術或者法則是金科玉律一成不變的。 很佩服那些勇於挑戰權威,推陳出新的勇者,是他們讓我們的技術不斷的變革更加的卓越。好像扯遠了,本文主要想談談兩個名詞,功能變數名稱發散和功能變數名稱收斂。 域 ...
  • 【對A/B測試的看法】 開發者在Dev Center中設置幾種應用變體,這幾種變體有幾個變數的值不一樣,比如有變體A和變體B(當然還可以加上變體C,Dev Center最多支持5個變體),A和B的不同在於Button的顏色btnColor,A是Amber,B是Blue 這些值設置好之後,Dev Ce ...
  • 與其他大部分編程語言不同,Swift 並不強制要求你在每條語句的結尾處使用分號(;),當然,你也可以按照你自己的習慣添加分號。有一種情況下必須要用分號,即你打算在同一行內寫多條獨立的語句 let you = "Forrest" ;print(you) ...
  • 1.在Storyboard滑鼠右鍵可以直接拖線的,如果你用的是外接的第三方滑鼠,沒必要按著 control 鍵再用滑鼠左鍵拖線 如果是觸控板的話,雙指按下去就可以直接拖線,帶3Dtouch功能的觸控板會比較好使 2.雙擊選中一個單詞,三擊選中一行,方便管理 3.刪除時, option + delet ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...