iOS 多線程 01,ios多線程01

來源:互聯網
上載者:User

iOS 多線程 01,ios多線程01

  • 進程

    • 進程是指在系統中正在啟動並執行一個應用程式
  • 線程

    • 1個進程要想執行任務,必須得有線程(每1個進程至少要有1條線程)
    • 1個線程中任務的執行是串列的(執行完上一個才能執行下一個)
  • 多線程

    • 1個進程中可以開啟多條線程,多條線程可以並行(同時)執行不同的任務
    • 線程可以並行, 但是每個線程中的任務還是串列
  • 多線程原理

    • 多線程並發(同時)執行,其實是CPU快速地在多條線程之間調度(切換)
  • 多線程優缺點

    • 優點
      • 能適當提高程式的執行效率
      • 能適當提高資源使用率(CPU、記憶體利用率)
    • 缺點
      • 線程越多,CPU在調度線程上的開銷就越大
      • 如果開啟大量的線程,會降低程式的效能
      • 程式設計更加複雜:比如線程之間的通訊、多線程的資料共用
  • pthread
    • 類型: C語言中類型的結尾通常 _t/Ref,而且不需要使用 *
    • /*參數:1. 線程代號的地址2. 線程的屬性3. 調用函數的指標  - void *(*)(void *)  - 傳回值 (函數指標)(參數)  - void * 和 OC 中的 id 是等價的4. 傳遞給該函數的參數傳回值:如果是0,表示正確如果是非0,表示錯誤碼*/NSString *str = @"jx";pthread_t thid;int res = pthread_create(&thid, NULL, &demo, (__bridge void *)(str));if (res == 0) {  NSLog(@"OK");} else {  NSLog(@"error %d", res);}
  • NSThread

    • 一個NSThread對象就代表一條線程
  • 建立線程的幾種方式

  • // 1.建立線程 NJThread *thread = [[NJThread alloc] initWithTarget:self selector:@selector(demo:) object:@"jx"]; // 設定線程名稱 [thread setName:@"ljx"]; // 設定線程的優先順序 // 優先順序僅僅說明被CPU調用的可能性更大   [thread setThreadPriority:1.0]; // 2.啟動線程 [thread start];
    - detach/performSelector    + 優點:簡單快捷    + 缺點:無法對線程進行更詳細的設定```objc// 1.建立線程[NSThread detachNewThreadSelector:@selector(demo:) toTarget:self withObject:@"jx"];// 1.建立線程// 注意: Swift中不能使用, 蘋果認為這個方法不安全    [self performSelectorInBackground:@selector(demo:) withObject:@"jx"];
  • 線程狀態
  •     啟動線程    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];[thread start];    // 進入就緒狀態 ->         運行狀態。當線程任務執行完畢,自動進入死亡狀態    阻塞(暫停)線程    + (void)sleepUntilDate:(NSDate *)date;    + (void)sleepForTimeInterval:(NSTimeInterval)ti;    // 進入阻塞狀態    強制停止線程    + (void)exit;    // 進入死亡狀態注意:一旦線程停止(死亡)了,就不能再次開啟任務   

    多線程的安全隱患

    • 被鎖定的代碼同一時刻只能有一個線程執行
    • @synchronized(鎖對象) { // 需要鎖定的代碼  }
  • 互斥鎖的優缺點 優點:能有效防止因多線程搶奪資源造成的資料安全問題 缺點:需要消耗大量的CPU資源

  • 互斥鎖注意點

    • 鎖定1份代碼只用1把鎖,用多把鎖是無效的
    • 鎖定範圍越大, 效能越差
  • 原子和非原子屬性

    • atomic:安全執行緒,需要消耗大量的資源
    • nonatomic:非安全執行緒,適合記憶體小的行動裝置
  • 自旋鎖 & 互斥鎖

    • 共同點 都能夠保證同一時間,只有一條線程執行鎖定範圍的代碼
    • 不同點
      • 互斥鎖:如果發現有其他線程正在執行鎖定的代碼,線程會進入"休眠"狀態,等待其他線程執行完畢,開啟鎖之後,線程會被"喚醒"
      • 自旋鎖:如果發現有其他線程正在執行鎖定的代碼,線程會"一直等待"鎖定代碼執行完成! 自旋鎖更適合執行非常短的代碼!
  • 線程間通訊
      • 子線程做耗時操作, 主線程更新資料
  • #import "ViewController.h"@interface ViewController ()@property (weak, nonatomic) IBOutlet UIImageView *imageView;@end@implementation ViewController- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{        // 開啟一個子線程下載圖片    [self performSelectorInBackground:@selector(downlod) withObject:nil];}- (void)downlod{    NSLog(@"%@", [NSThread currentThread]);    // 1.下載圖片     NSURL *url = [NSURL URLWithString:@"http://pic.4j4j.cn/upload/pic/20130531/07ed5ea485.jpg"];     NSData *data = [NSData dataWithContentsOfURL:url];    // 2.將二進位轉換為圖片    UIImage *image = [UIImage imageWithData:data];        // 3.跟新UI#warning 注意: 千萬不要在子線程中更新UI, 會出問題        /*     waitUntilDone:      YES: 如果傳入YES, 那麼會等待updateImage方法執行完畢, 才會繼續執行後面的代碼     NO:  如果傳入NO, 那麼不會等待updateImage方法執行完畢, 就可以繼續之後後面的代碼     */    /*    [self performSelectorOnMainThread:@selector(updateImage:) withObject:image waitUntilDone:NO];     */        // 開發中常用//    [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES];        // 可以在指定的線程中, 調用指定對象的指定方法    [self performSelector:@selector(updateImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];    }- (void)updateImage:(UIImage *)image{    NSLog(@"%@", [NSThread currentThread]);    // 3.更新UI    self.imageView.image = image;    }
  • GCD
  • GCD中有2個核心概念

    • 任務:執行什麼操作
    • 隊列:用來存放任務
  • 執行任務

    • 同步方法: dispatch_sync
    • 非同步方法呼叫: dispatch_async
    • 同步和非同步區別
      • 同步:只能在當前線程中執行任務,不具備開啟新線程的能力
      • 非同步:可以在新的線程中執行任務,具備開啟新線程的能力
  • 隊列

    • 並發隊列
      • 可以讓多個任務並發(同時)執行(自動開啟多個線程同時執行任務)
      • 並發功能只有在非同步(dispatch_async)函數下才有效
      • GCD預設已經提供了全域的並發隊列,供整個應用使用,可以無需手動建立            使用dispatch_get_global_queue函數獲得全域的並發隊列            dispatch_queue_t dispatch_get_global_queue(            dispatch_queue_priority_t priority, //                    隊列的優先順序            unsigned long flags); // 此參數暫時無用,用0即可            獲得全域並發隊列            dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);            全域並發隊列的優先順序            #define DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高            #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 預設(中)            #define DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低            #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 後台

         

    • 串列隊列    * 讓任務一個接著一個地執行(一個任務執行完畢後,再執行下一個任務)
    •         GCD中獲得串列有2種途徑        使用dispatch_queue_create函數建立串列隊列        // 建立串列隊列(隊列類型傳遞NULL或者DISPATCH_QUEUE_SERIAL)        dispatch_queue_t queue = dispatch_queue_create("com.520it.queue", NULL);        使用主隊列(跟主線程相關聯的隊列)        主隊列是GCD內建的一種特殊的串列隊列        放在主隊列中的任務,都會放到主線程中執行        使用dispatch_get_main_queue()獲得主隊列        dispatch_queue_t queue = dispatch_get_main_queue();
    • 注意點

      同步和非同步主要影響:能不能開啟新的線程
      • 同步:只是在當前線程中執行任務,不具備開啟新線程的能力
      • 非同步:可以在新的線程中執行任務,具備開啟新線程的能力
      並發和串列主要影響:任務的執行方式
      • 並發:允許多個任務並發(同時)執行
      • 串列:一個任務執行完畢後,再執行下一個任務
    • 各種任務隊列搭配

      • 同步 + 串列 *
      • 同步 + 並發 *
      • 非同步 + 串列 *
      • 非同步 + 並發 *
      • 非同步 + 主隊列 *
      • 同步 + 主隊列 *
    • GCD線程間通訊

    • dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{    // 執行耗時的非同步作業...      dispatch_async(dispatch_get_main_queue(), ^{        // 回到主線程,執行UI重新整理操作        });});
    • GCD其它用法
    • 延時執行
    • dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{    // 2秒後執行這裡的代碼...});

       

    • 一次性代碼

      • 使用dispatch_once函數能保證某段代碼在程式運行過程中只被執行1次
    • static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ // 只執行1次的代碼(這裡面預設是安全執行緒的) });

       

    • 快速迭代
    • dispatch_apply(10, dispatch_get_global_queue(0, 0), ^(size_t index){    // 執行10次代碼,index順序不確定});
    • barrier
      • 在前面的任務執行結束後它才執行,而且它後面的任務等它執行完成之後才會執行
      • 不能是全域的並發隊列
      • 所有的任務都必須在一個隊列中
      • dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
    • 隊列組
    • dispatch_group_t group =  dispatch_group_create();dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{    // 執行1個耗時的非同步作業});dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{    // 執行1個耗時的非同步作業});dispatch_group_notify(group, dispatch_get_main_queue(), ^{    // 等前面的非同步作業都執行完畢後,回到主線程...});
    • iOS中多線程的實現方案

    • 單例模式

      • 單例模式的作用

        - 可以保證在程式運行過程,一個類只有一個執行個體,而且該執行個體易於供外界訪問,從而方便地控制了執行個體個數,並節約系統資源
      • 單例模式的使用場合

        • 在整個應用程式中,共用一份資源(這份資源只需要建立初始化1次)
      • ARC中,單例模式的實現

      • 在.m中保留一個全域的static的執行個體        static id _instance;        重寫allocWithZone:方法,在這裡建立唯一的執行個體(注意安全執行緒)        + (instancetype)allocWithZone:(struct _NSZone *)zone        {            static dispatch_once_t onceToken;            dispatch_once(&onceToken,^{            _instance = [super allocWithZone:zone];            });             return _instance;        }        提供1個類方法讓外界訪問唯一的執行個體        + (instancetype)sharedInstance        {            static dispatch_once_t onceToken;            dispatch_once(&onceToken, ^{            _instance = [[self alloc] init];             });            return _instance;        }        實現copyWithZone:方法        - (id)copyWithZone:(struct _NSZone *)zone        {            return _instance;        }        注意點            // 注意點: 單例是不可以繼承的, 如果繼承引發問題            // 如果先建立父類, 那麼永遠都是父類            // 如果先建立子類, 那麼永遠都是子類

         

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.