iOS 多執行緒筆記_( 1 )

躍然發表於2015-10-08

1、一個NSThread物件就代表一條執行緒

建立、啟動執行緒
NSThread *thread = [[NSThread alloc] initWithTarget:self start];selector:@selector(run) object:nil];

[thread

// 執行緒一啟動,就會告訴 CPU 準備就緒,可以隨時接受 CPU 排程! CPU 排程當前執行緒之後,就會線上程thread中執行self的run方法

主執行緒相關用法

  • (NSThread *)mainThread; // 獲得主執行緒
  • (BOOL)isMainThread; // 是否為主執行緒
  • (BOOL)isMainThread; // 是否為主執行緒

2、獲得當前執行緒

NSThread *current = [NSThread currentThread];

執行緒的排程優先順序

  • (double)threadPriority;
  • (BOOL)setThreadPriority:(double)p;
  • (double)threadPriority;
  • (BOOL)setThreadPriority:(double)p;
  • 排程優先順序的取值範圍是0.0 ~ 1.0,預設0.5,值越大,優先順序越高

執行緒的名字

  • (void)setName:(NSString *)n;
  • (NSString *)name;

三、建立執行緒後自動啟動執行緒

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

隱式建立並啟動執行緒

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

上述2種建立執行緒方式的優缺點

優點:簡單快捷

缺點:無法對執行緒進行更詳細的設定

四、互斥鎖使用格式

@synchronized(鎖物件) { // 需要鎖定的程式碼 }

注意:鎖定1份程式碼只用1把鎖,用多把鎖是無效的

互斥鎖的優缺點

優點:能有效防止因多執行緒搶奪資源造成的資料安全問題

缺點:需要消耗大量的CPU資源

互斥鎖的使用前提:多條執行緒搶奪同一塊資源

相關專業術語:執行緒同步
執行緒同步的意思是:多條執行緒在同一條線上執行(按順序地執行任務)
互斥鎖,就是使用了執行緒同步技術

五、OC在定義屬性時有nonatomic和atomic兩種選擇

  • atomic:原子屬性,為setter方法加鎖(預設就是atomic)

    nonatomic:非原子屬性,不會為setter方法加鎖

  • nonatomic和atomic對比

    atomic:執行緒安全,需要消耗大量的資源

    nonatomic:非執行緒安全,適合記憶體小的移動裝置

  • iOS開發的建議

    所有屬性都宣告為nonatomic

    儘量避免多執行緒搶奪同一塊資源

    儘量將加鎖、資源搶奪的業務邏輯交給伺服器端處理,減小移動客戶端的壓力

六、既然多執行緒這麼爽, 執行緒是不是越多越好呢?

<1> 開啟執行緒需要消耗一定的記憶體(預設情況下,執行緒佔用 512KB 的棧區空間);
<2> 會使應用程式增加很多程式碼!程式碼變多之後,程式複雜性就會提高!
<3> CPU 在多條執行緒之間來回切換!執行緒越多, CPU就越累!

建議: 在移動應用的開發中; 一般只開3~5條執行緒!

七、重點:為什麼要使用橋接?你是怎麼進行混合開發的?

{

    橋接 (__bridge) :C 和 OC 之間傳遞資料的時候需要使用橋接! why?為什麼呢?

    1.記憶體管理:
        在 OC 中,如果是在 ARC環境下開發,編譯器在編譯的時候會根據程式碼結構,自動為 OC 程式碼新增 retain/release/autorelease等.   ----->自動記憶體管理(ARC)的原理!

        但是, ARC只負責 OC 部分的記憶體管理!不會負責 C 語言部分程式碼的記憶體管理!
        也就是說!即使是在 ARC 的開發環境中!如果使用的 C 語言程式碼出現了 retain/copy/new/create等字樣呢!我們都需要手動為其新增 release 操作!否則會出現記憶體洩露!

        在混合開發時(C 和 OC 程式碼混合),C 和 OC 之間傳遞資料需要使用 __bridge 橋接,目的就是為了告訴編譯器如何管理記憶體

        在 MRC中不需要使用橋接! 因為都需要手動進行記憶體管理!

    2.資料型別轉換:

        Foundation 和 Core Foundation框架的資料型別可以互相轉換的
        Foundation :  OC
        Core Foundation : C語言

        NSString *str = @"123"; // Foundation
        CFStringRef str2 = (__bridge CFStringRef)str; // Core Foundation
        NSString *str3 = (__bridge NSString *)str2;
            CFArrayRef ---- NSArray
            CFDictionaryRef ---- NSDictionary
            CFNumberRef ---- NSNumber

        Core Foundation中手動建立的資料型別,都需要手動釋放

        CGPathRef path = CGPathCreateMutable();
        CGPathRetain(path);

        CGPathRelease(path);
        CGPathRelease(path);

    3.橋接的新增:
        利用 Xcode 提示自動新增! --簡單/方便/快速
    /**
     凡是函式名中帶有create\copy\new\retain等字眼, 都應該在不需要使用這個資料的時候進行release
     GCD的資料型別在ARC環境下不需要再做release
     CF(Core Foundation)的資料型別在ARC\MRC環境下都需要再做release
    */    

}

八、iOS中多執行緒實現方案2.NSThread - 1基本使用

重點:1.三種建立執行緒! 2.常用方法!
{
    1.NSThread: 一個 NSThread 就代表一個執行緒物件!
    // OC語言 / 使用物件導向 / 需要手動管理執行緒生命週期(建立/銷燬等)

    2.三種多執行緒實現方案:

    1> 先建立,後啟動
    // 建立
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(download:) object:nil];
    // 啟動
    [thread start];

    2> 建立完自動啟動
    [NSThread detachNewThreadSelector:@selector(download:) toTarget:self withObject:nil];

    3> 隱式建立(自動啟動)
    [self performSelectorInBackground:@selector(download:) withObject:nil];

    3.常用方法:
     名字/獲得主執行緒/獲得當前執行緒/阻塞執行緒/退出執行緒
    // 不常用: 棧區大小/優先順序
    1> 獲得當前執行緒
    + (NSThread *)currentThread;

    2> 獲得主執行緒
    + (NSThread *)mainThread;

    3> 睡眠(暫停)執行緒
    + (void)sleepUntilDate:(NSDate *)date;
    + (void)sleepForTimeInterval:(NSTimeInterval)ti;

    4> 設定執行緒的名字
    - (void)setName:(NSString *)n;
    - (NSString *)name;
}

九、重點:1.執行緒同步技術! 2.理解資源共享

{
    當多條執行緒訪問同一塊資源的時候,就會出現資料錯亂和資料安全的問題!

    1.ATM機取錢; 賣票;

    2.解決方案:互斥鎖 @synchronized(鎖物件self){  /*需要鎖住的程式碼,越少越好!*/ }   ------- 廁所加鎖!

    注意:鎖定一份程式碼只用一把鎖,用多把鎖是無效的!

    優點:能有效防止因多執行緒搶奪資源而引起的資料安全問題!
    缺點:需要消耗大量的CPU資源!

    結論:儘量少加鎖!互斥鎖的使用前提是多條執行緒搶奪同一塊資源!

    3.新增互斥鎖技巧: [[NSUserDefaults standardUserDefaults] synchronize];

    4.執行緒同步技術:  ----- 互斥鎖使用了執行緒同步技術!

    多條執行緒在同一條線上按順序執行任務!

    5.執行緒安全:保證多條執行緒進行讀寫操作,都能夠得到正確的結果!'鎖' 來實現執行緒安全!
}

十、為什麼要在主執行緒更新UI?

因為UIKit 框架都不是執行緒安全的!為了得到更好的使用者體驗,UIKit框架犧牲了執行緒安全;

所以我們要在主執行緒更新UI;

十一、下載圖片 更新 UI

/*------------------------- iOS中多執行緒實現方案2.NSThread - 4執行緒間通訊 -------------------------*/
1.下載圖片? 更新 UI?
{
    1.後臺執行緒(子執行緒)下載圖片;

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

    2.主執行緒更新 UI.

    執行緒間通訊常用方法:

    // 最後一個引數:是否等待呼叫方法執行結束!
    <1>[self performSelectorOnMainThread:@selector(setImageWithImage:) withObject:nil waitUntilDone:YES];

    <2>[self performSelector:@selector(setImageWithImage:) onThread:[NSThread mainThread] withObject:nil waitUntilDone:YES];
}

十二、執行緒狀態

執行緒狀態.png

十三、cell下載圖片思路

cell下載圖片思路 – 無沙盒快取.png

cell下載圖片思路 – 有沙盒快取.png

相關文章