麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

iOS多線程01

2019-11-14 18:20:38
字體:
供稿:網(wǎng)友
  • 進(jìn)程

    • 進(jìn)程是指在系統(tǒng)中正在運(yùn)行的一個應(yīng)用程序
  • 線程

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

    • 1個進(jìn)程中可以開啟多條線程,多條線程可以并行(同時)執(zhí)行不同的任務(wù)
    • 線程可以并行, 但是每個線程中的任務(wù)還是串行
  • 多線程原理

    • 多線程并發(fā)(同時)執(zhí)行,其實(shí)是CPU快速地在多條線程之間調(diào)度(切換)
  • 多線程優(yōu)缺點(diǎn)

    • 優(yōu)點(diǎn)
      • 能適當(dāng)提高程序的執(zhí)行效率
      • 能適當(dāng)提高資源利用率(CPU、內(nèi)存利用率)
    • 缺點(diǎn)
      • 線程越多,CPU在調(diào)度線程上的開銷就越大
      • 如果開啟大量的線程,會降低程序的性能
      • 程序設(shè)計(jì)更加復(fù)雜:比如線程之間的通信、多線程的數(shù)據(jù)共享

  • pthread
    • 類型: C語言中類型的結(jié)尾通常 _t/Ref,而且不需要使用 *
    • /*參數(shù):1. 線程代號的地址2. 線程的屬性3. 調(diào)用函數(shù)的指針  - void *(*)(void *)  - 返回值 (函數(shù)指針)(參數(shù))  - void * 和 OC 中的 id 是等價的4. 傳遞給該函數(shù)的參數(shù)返回值:如果是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對象就代表一條線程
  • 創(chuàng)建線程的幾種方式

  • // 1.創(chuàng)建線程 NJThread *thread = [[NJThread alloc] initWithTarget:self selector:@selector(demo:) object:@"jx"]; // 設(shè)置線程名稱 [thread setName:@"ljx"]; // 設(shè)置線程的優(yōu)先級 // 優(yōu)先級僅僅說明被CPU調(diào)用的可能性更大   [thread setThreadPRiority:1.0]; // 2.啟動線程 [thread start];
    - detach/performSelector    + 優(yōu)點(diǎn):簡單快捷    + 缺點(diǎn):無法對線程進(jìn)行更詳細(xì)的設(shè)置```objc// 1.創(chuàng)建線程[NSThread detachNewThreadSelector:@selector(demo:) toTarget:self withObject:@"jx"];// 1.創(chuàng)建線程// 注意: Swift中不能使用, 蘋果認(rèn)為這個方法不安全    [self performSelectorInBackground:@selector(demo:) withObject:@"jx"];
  • 線程狀態(tài)
  •     啟動線程    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];[thread start];    // 進(jìn)入就緒狀態(tài) ->         運(yùn)行狀態(tài)。當(dāng)線程任務(wù)執(zhí)行完畢,自動進(jìn)入死亡狀態(tài)    阻塞(暫停)線程    + (void)sleepUntilDate:(NSDate *)date;    + (void)sleepForTimeInterval:(NSTimeInterval)ti;    // 進(jìn)入阻塞狀態(tài)    強(qiáng)制停止線程    + (void)exit;    // 進(jìn)入死亡狀態(tài)注意:一旦線程停止(死亡)了,就不能再次開啟任務(wù)   如圖:

    多線程的安全隱患

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

  • 互斥鎖注意點(diǎn)

    • 鎖定1份代碼只用1把鎖,用多把鎖是無效的
    • 鎖定范圍越大, 性能越差

  • 原子和非原子屬性

    • atomic:線程安全,需要消耗大量的資源
    • nonatomic:非線程安全,適合內(nèi)存小的移動設(shè)備
  • 自旋鎖 & 互斥鎖

    • 共同點(diǎn) 都能夠保證同一時間,只有一條線程執(zhí)行鎖定范圍的代碼
    • 不同點(diǎn)
      • 互斥鎖:如果發(fā)現(xiàn)有其他線程正在執(zhí)行鎖定的代碼,線程會進(jìn)入"休眠"狀態(tài),等待其他線程執(zhí)行完畢,打開鎖之后,線程會被"喚醒"
      • 自旋鎖:如果發(fā)現(xiàn)有其他線程正在執(zhí)行鎖定的代碼,線程會"一直等待"鎖定代碼執(zhí)行完成! 自旋鎖更適合執(zhí)行非常短的代碼!

  • 線程間通信
      • 子線程做耗時操作, 主線程更新數(shù)據(jù)
  • #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.將二進(jìn)制轉(zhuǎn)換為圖片    UIImage *image = [UIImage imageWithData:data];        // 3.跟新UI#warning 注意: 千萬不要在子線程中更新UI, 會出問題        /*     waitUntilDone:      YES: 如果傳入YES, 那么會等待updateImage方法執(zhí)行完畢, 才會繼續(xù)執(zhí)行后面的代碼     NO:  如果傳入NO, 那么不會等待updateImage方法執(zhí)行完畢, 就可以繼續(xù)之后后面的代碼     */    /*    [self performSelectorOnMainThread:@selector(updateImage:) withObject:image waitUntilDone:NO];     */        // 開發(fā)中常用//    [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES];        // 可以在指定的線程中, 調(diào)用指定對象的指定方法    [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個核心概念

    • 任務(wù):執(zhí)行什么操作
    • 隊(duì)列:用來存放任務(wù)
  • 執(zhí)行任務(wù)

    • 同步方法: dispatch_sync
    • 異步方法: dispatch_async
    • 同步和異步的區(qū)別
      • 同步:只能在當(dāng)前線程中執(zhí)行任務(wù),不具備開啟新線程的能力
      • 異步:可以在新的線程中執(zhí)行任務(wù),具備開啟新線程的能力
  • 隊(duì)列

    • 并發(fā)隊(duì)列
      • 可以讓多個任務(wù)并發(fā)(同時)執(zhí)行(自動開啟多個線程同時執(zhí)行任務(wù))
      • 并發(fā)功能只有在異步(dispatch_async)函數(shù)下才有效
      • GCD默認(rèn)已經(jīng)提供了全局的并發(fā)隊(duì)列,供整個應(yīng)用使用,可以無需手動創(chuàng)建            使用dispatch_get_global_queue函數(shù)獲得全局的并發(fā)隊(duì)列            dispatch_queue_t dispatch_get_global_queue(            dispatch_queue_priority_t priority, //                    隊(duì)列的優(yōu)先級            unsigned long flags); // 此參數(shù)暫時無用,用0即可            獲得全局并發(fā)隊(duì)列            dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);            全局并發(fā)隊(duì)列的優(yōu)先級            #define DISPATCH_QUEUE_PRIORITY_HIGH 2 //            #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默認(rèn)(中)            #define DISPATCH_QUEUE_PRIORITY_LOW (-2) //            #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 后臺

         

    • 串行隊(duì)列    * 讓任務(wù)一個接著一個地執(zhí)行(一個任務(wù)執(zhí)行完畢后,再執(zhí)行下一個任務(wù))
    •         GCD中獲得串行有2種途徑        使用dispatch_queue_create函數(shù)創(chuàng)建串行隊(duì)列        // 創(chuàng)建串行隊(duì)列(隊(duì)列類型傳遞NULL或者DISPATCH_QUEUE_SERIAL)        dispatch_queue_t queue = dispatch_queue_create("com.520it.queue", NULL);        使用主隊(duì)列(跟主線程相關(guān)聯(lián)的隊(duì)列)        主隊(duì)列是GCD自帶的一種特殊的串行隊(duì)列        放在主隊(duì)列中的任務(wù),都會放到主線程中執(zhí)行        使用dispatch_get_main_queue()獲得主隊(duì)列        dispatch_queue_t queue = dispatch_get_main_queue();
    • 注意點(diǎn)

      同步和異步主要影響:能不能開啟新的線程
      • 同步:只是在當(dāng)前線程中執(zhí)行任務(wù),不具備開啟新線程的能力
      • 異步:可以在新的線程中執(zhí)行任務(wù),具備開啟新線程的能力
      并發(fā)和串行主要影響:任務(wù)的執(zhí)行方式
      • 并發(fā):允許多個任務(wù)并發(fā)(同時)執(zhí)行
      • 串行:一個任務(wù)執(zhí)行完畢后,再執(zhí)行下一個任務(wù)
    • 各種任務(wù)隊(duì)列搭配

      • 同步 + 串行 *
      • 同步 + 并發(fā) *
      • 異步 + 串行 *
      • 異步 + 并發(fā) *
      • 異步 + 主隊(duì)列 *
      • 同步 + 主隊(duì)列 *
    • GCD線程間通信

    • dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{    // 執(zhí)行耗時的異步操作...      dispatch_async(dispatch_get_main_queue(), ^{        // 回到主線程,執(zhí)行UI刷新操作        });});
    • GCD其它用法
    • 延時執(zhí)行
    • dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{    // 2秒后執(zhí)行這里的代碼...});

       

    • 一次性代碼

      • 使用dispatch_once函數(shù)能保證某段代碼在程序運(yùn)行過程中只被執(zhí)行1次
    • static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ // 只執(zhí)行1次的代碼(這里面默認(rèn)是線程安全的) });

       

    • 快速迭代
    • dispatch_apply(10, dispatch_get_global_queue(0, 0), ^(size_t index){    // 執(zhí)行10次代碼,index順序不確定});
    • barrier
      • 在前面的任務(wù)執(zhí)行結(jié)束后它才執(zhí)行,而且它后面的任務(wù)等它執(zhí)行完成之后才會執(zhí)行
      • 不能是全局的并發(fā)隊(duì)列
      • 所有的任務(wù)都必須在一個隊(duì)列中
      • dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
    • 隊(duì)列組
    • dispatch_group_t group =  dispatch_group_create();dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{    // 執(zhí)行1個耗時的異步操作});dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{    // 執(zhí)行1個耗時的異步操作});dispatch_group_notify(group, dispatch_get_main_queue(), ^{    // 等前面的異步操作都執(zhí)行完畢后,回到主線程...});
    • iOS中多線程的實(shí)現(xiàn)方案

      • 如圖:
    • 單例模式

      • 單例模式的作用

        - 可以保證在程序運(yùn)行過程,一個類只有一個實(shí)例,而且該實(shí)例易于供外界訪問,從而方便地控制了實(shí)例個數(shù),并節(jié)約系統(tǒng)資源
      • 單例模式的使用場合

        • 在整個應(yīng)用程序中,共享一份資源(這份資源只需要創(chuàng)建初始化1次)
      • ARC中,單例模式的實(shí)現(xiàn)

      • 在.m中保留一個全局的static的實(shí)例        static id _instance;        重寫allocWithZone:方法,在這里創(chuàng)建唯一的實(shí)例(注意線程安全)        + (instancetype)allocWithZone:(struct _NSZone *)zone        {            static dispatch_once_t onceToken;            dispatch_once(&onceToken,^{            _instance = [super allocWithZone:zone];            });             return _instance;        }        提供1個類方法讓外界訪問唯一的實(shí)例        + (instancetype)sharedInstance        {            static dispatch_once_t onceToken;            dispatch_once(&onceToken, ^{            _instance = [[self alloc] init];             });            return _instance;        }        實(shí)現(xiàn)copyWithZone:方法        - (id)copyWithZone:(struct _NSZone *)zone        {            return _instance;        }        注意點(diǎn)            // 注意點(diǎn): 單例是不可以繼承的, 如果繼承引發(fā)問題            // 如果先創(chuàng)建父類, 那么永遠(yuǎn)都是父類            // 如果先創(chuàng)建子類, 那么永遠(yuǎn)都是子類

         


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 色柚视频网站ww色 | 亚洲精品久久久久久久久久 | 国产欧美在线观看不卡一 | 成人男女免费视频 | 久草在线资源福利站 | 免费福利在线视频 | 久久久久北条麻妃免费看 | 色婷婷久久一区二区 | 国产男人的天堂 | 国产91丝袜在线熟 | 中午字幕无线码一区2020 | 中日无线码1区 | 一本一本久久a久久精品综合小说 | 国产精品视频二区不卡 | 国产成人高清成人av片在线看 | 欧美一级电影网站 | 98色视频| 经典三级av在线 | 久久tv免费国产高清 | 欧美日韩亚洲精品一区二区三区 | 精品一区二区久久久久久久网精 | 午夜国内精品a一区二区桃色 | 一本色道久久综合狠狠躁篇适合什么人看 | 九色中文 | 欧美日韩视频在线播放 | 欧美日韩在线视频一区 | videos高潮 | 久久久精品视频免费 | 亚洲最大的成人网 | 最新福利在线 | 狠狠干天天操 | 午夜av男人的天堂 | 亚洲天堂一级片 | 欧美人的天堂一区二区三区 | 日韩激情| 黄污在线看| 国产亚洲精品视频中文字幕 | 国产1区在线 | 激情综合婷婷久久 | 毛片在线免费观看网址 | 性欧美性欧美 |