天天看點

iOS多線程,NSThread ,NSOperationQueue ,GCDiOS 多線程

iOS 多線程

1、程序跟線程

程序:

一個程式至少有一個程序,一個程序至少有一個線程、

        有獨立的記憶體空間、

        同一個程序中的線程,共享記憶體中的記憶體跟資源、

     程序相當與一個靜态容器,裡面裝了很多活動的線程。

線程:

     每一個程式都有一個主線程,程式啟動的時候建立(調用main 來啟動)、

     主線程的生命周前,和應用程式是綁定的,程式退出時候,主線程也就停止了、

     多線程,一個應用程式有多個線程,提高cpu的使用律,防止主線程堵塞、

      任何有可能堵塞主線程的的任務都不要再主線程執行(比如網絡請求)。

程序跟線程:我覺得這樣更好了解,程序就好比我們的道路(道路相當于程序),如果隻有一個車道(車道相當于線程),車流量一多,就可能會造成道路的堵塞,萬一前面哪輛車碰撞了。整個道路就癱瘓堵塞了。這樣子話,我們就可以開辟多個車道(線程)來緩解、加速,交通狀況。當然。如果車道(線程)增多就會增加資源的耗用。這也就是多線程會損耗一定的資源。一個道路可以開辟多個車道,(一個程序,裡面可以有多個線程); ps:個人了解,歡迎糾正

iOS多線程,NSThread ,NSOperationQueue ,GCDiOS 多線程

2、iOS 多線程多種實作:

2.1、NSThread 

// ------------------多線程第1種方式

    NSThread *thread = [[NSThreadalloc]initWithTarget:self selector:@selector(thread) object:nil];

    [thread start];

      // ------------------多線程第2種方式

   [NSThread detachNewThreadSelector:@selector(thread) toTarget:self withObject:nil];

// ------------------多線程第3種方式

    [self performSelectorInBackground:@selector(thread) withObject:nil];

//回到主線程

    [self performSelectorOnMainThread:@selector(thread) withObject:nil waitUntilDone:NO];

NSlog(@"1111");

      waitUntilDone 等待上面方法執行後再執行下面的内容,例如:如果waitUntilDone為yes,則等待方法執行完再列印111,如果為no,就執行方法,與列印111,同步執行!

2.2、NSOperationQueue  

NSOperation 是一個抽象類,用來封裝一個獨立任務的代碼與資料。不能直接使用該類,通過子類化或系統提供的子類來完成任務,NSOperationQueue是其系統提供的子類。 NSOperationQueue 用來管理operation 集合,決定他們的執行順序,當一個 operation 被添加到queue後,一旦有多餘的線程來執行這個 operation 。那麼這個 operation 就會馬上被執行。

// -------------------多線程第4種方式

//直接代碼塊方式實作

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

[operationQ addOperationWithBlock:^{

       for (int i=0; i<50; i++) {

            NSLog(@"線程1111:%d",i);

        }  }];

// ------------------多線程第5種方式

     //建立線程隊列(線程池)

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

    //線程的最大并發數,(如果有五個任務,并發為2的話,就是先執行前面兩個,前面兩個執行完一個才會輪到後面的任務執行)

    operationQ.maxConcurrentOperationCount = 2;

   NSInvocationOperation *inOperation =[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(thread)object:nil];

    //線程的優先級

    [inOperation setQueuePriority:NSOperationQueuePriorityVeryLow];

    NSInvocationOperation *inOperation2 =[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(thread1)object:nil];

     //線程的優先級  

  [inOperation2 setQueuePriority:NSOperationQueuePriorityHigh];

//如果并發數是1得話、先添加進來的先執行

     [operationQ addOperation:inOperation];

[operationQ addOperation:inOperation2];

2.3、GCD(Grand central dispatch) 一個純 c 語言 寫的庫,

GCD 的優點 :

     在多核的硬體上,性能更佳!

     并且操作簡單,程式猿隻需要告訴GCD 你要執行什麼任務。不需要編寫任何線程管理的代碼;

如何用?

     用之前先了解:

     GCD 的兩個核心的概念:

     1、任務:執行什麼樣的操作

      2、隊列:用來存放任務的。

任務

     1、同步,第一個參數要求我們放入一個隊列,第二個參數就是我們要做的任務

     dispatch_sync(<#dispatch_queue_tqueue#>, <#^(void)block#>)

     2、異步

    dispatch_async(<#dispatch_queue_tqueue#>, <#^(void)block#>)

    .同步和異步的差別

     同步:在目前線程中執行

     異步:在另一條線程中執行

 隊列

     1、并發隊列(Concurrent Dispatch Queue),多個任務同時執行

     dispatch_queue_t queue =dispatch_get_global_queue(<#long identifier#>, <#unsigned longflags#>)

     2、串行隊列(Serial Dispatch Queue),前一個任務執行完了,在執行下一個任務

     dispatch_queue_create(<#const char *label#>,<#dispatch_queue_attr_t attr#>)

 NSLog(@"主線程:%@",[NSThread mainThread]);

    //(3)将同步執行,放入并發隊列中

    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);

    dispatch_sync(queue, ^{

        NSLog(@"11111 ===== >%@",[NSThread currentThread]);

    });

    dispatch_sync(queue, ^{

        NSLog(@"22222 ===== >%@",[NSThread currentThread]);

    });

    dispatch_sync(queue, ^{

        NSLog(@"33333 ===== >%@",[NSThread currentThread]);

    });

  dispatch_async(dispatch_get_main_queue(), ^{

            //回到主線程

        });

};

    //總結:不會開辟新線程,并發都失效了。。

(6)小結

    說明:同步函數不具備開啟線程的能力,無論是什麼隊列都不會開啟線程;異步函數具備開啟線程的能力,開啟幾條線程由隊列決定(串行隊列隻會開啟一條新的線程,并發隊列會開啟多條線程)。

          同步函數

          (1)并發隊列:不會開線程

          (2)串行隊列:不會開線程

          異步函數

          (1)并發隊列:能開啟N條線程

          (2)串行隊列:開啟1條線程

3、總結:

在開發中要注意: 當你啟動新線程去執行某個任務的時候(比如,做網絡請求),最終請求結束後,要回到主線程去更新ui。 回到主線程的方式” 1、

//回到主線程

    [self performSelectorOnMainThread:@selector(thread) withObject:nil waitUntilDone:NO];

NSlog(@"1111");

      waitUntilDone 等待上面方法執行後再執行下面的内容,例如:如果waitUntilDone為yes,則等待方法執行完再列印111,如果為no,就執行方法,與列印111,同步執行!

2、

        dispatch_async(dispatch_get_main_queue(), ^{

            //回到主線程

        });

感謝糾正!

ps:每天進步一點點,做一個快樂的程式猿!