簡介ios
NSthread是蘋果官方提供面向對象操做線程的技術,簡單方便,能夠直接操做線程對象,不過須要本身控制線程的生命週期。在平時使用較少,經常使用的就是下面的方法來獲取當前線程。macos
[NSThread currentThread]
使用編程
1.實例初始化、屬性和實例方法數組
初始化函數
切記下面兩個方法初始化的NSThread必須手動start開啓線程
//建立線程 NSThread *newThread = [[NSThread alloc]initWithTarget:self selector:@selector(demo:) object:@"Thread"]; //或者 NSThread *newThread=[[NSThread alloc]init]; NSThread *newThread= [[NSThread alloc]initWithBlock:^{ NSLog(@"initWithBlock"); }];
屬性oop
線程字典ui
/** 每一個線程都維護了一個鍵-值的字典,它能夠在線程裏面的任何地方被訪問。 你可使用該字典來保存一些信息,這些信息在整個線程的執行過程當中保持不變。 好比,你可使用它來存儲在你的整個線程過程當中 Run loop 裏面屢次迭代的狀態信息。 NSThread實例可使用如下方法 */ @property (readonly, retain) NSMutableDictionary *threadDictionary; NSMutableDictionary *dict = [thread threadDictionary];
優先級spa
@property double threadPriority ; //優先級
線程優先級線程
/** NSQualityOfService: NSQualityOfServiceUserInteractive:最高優先級,主要用於提供交互UI的操做,好比處理點擊事件,繪製圖像到屏幕上 NSQualityOfServiceUserInitiated:次高優先級,主要用於執行須要當即返回的任務 NSQualityOfServiceDefault:默認優先級,當沒有設置優先級的時候,線程默認優先級 NSQualityOfServiceUtility:普通優先級,主要用於不須要當即返回的任務 NSQualityOfServiceBackground:後臺優先級,用於徹底不緊急的任務 */ @property NSQualityOfService qualityOfService
線程名稱調試
@property (nullable, copy) NSString *name;
線程使用棧區大小,默認是512k
@property NSUInteger stackSize ;
線程狀態(正在執行、執行結束、是否能夠取消)
@property (readonly, getter=isExecuting) BOOL executing; @property (readonly, getter=isFinished) BOOL finished; @property (readonly, getter=isCancelled) BOOL cancelled;
實例方法
// 啓動線程 實例化線程須要手動啓動才能運行 - (void)start; [thread stary] // 是否爲主線程 - (BOOL)isMainThread; isMain = [thread isMainThread]; //設置線程名稱 - (void)setName:(NSString *) name; [thraed setName:@"name"]; // 取消線程 - (void)cancel; [thread cancel]; // 線程的入口函數 - (void)main; [thread main]; // 線程是否正在執行 - (void)isExecuting; isRunning=[thread isExecuting]; // 線程是否已經結束 - (void)isFinished; isEnd=[thread isFinished]; // 線程是否撤銷 - (void)isCancelled; isCancel=[thread isCancelled];
類建立方法
/* 建立子線程並開始 建立後就可執行,不須要手動開啓
可是不能獲取NSThread對象 */ /** block方式 具體的任務在Block中執行 */ + (void)detachNewThreadWithBlock:(void (^)(void))block; /** SEL方式 利用selector方法初始化NSThread,target指selector方法從屬於的對象 selector方法也 是指定的target對象的方法 */ + (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(nullable id)argument;
類使用方法
// 獲取當前線程 + (void)currentThread; [NSThread currentThread]; //當前代碼運行所在線程是否爲子線程 + (BOOL)isMultiThreaded; isMulti = [NSThread isMultiThreaded]; // 當前代碼所在線程睡到指定時間 + (void)sleepUntilDate: (NSDate *)date; [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]]; // 線程沉睡時間間隔,這個方法在設置啓動頁間隔的時候比較常見 + (void)sleepForTimeInterval: (NSTimeInterval)time; [NSThread sleepForTimeInterval:1.0]; // 退出當前線程 + (void)exit; [NSThread exit]; // 設置當前線程優先級 + (double)threadPriority; double dPriority=[NSThread threadPriority]; // 給當前線程設定優先級,調度優先級的取值範圍是0.0 ~ 1.0,默認0.5,值越大,優先級越高。 + (BOOL)setThreadPriority:(double)priority; BOOL isSetting=[NSThread setThreadPriority:(0.0~1.0)]; // 線程的調用都會有行數的調用函數的調用,就會有棧返回地址的記錄, 在這裏返回的是函數調用返回的虛擬地址 說白了就是在在該先出中函數調用的虛擬地址的數組 + (NSArray *)callStackReturnAddresses; NSArray *addressArray=[NSThread callStackReturnAddresses]; // 同上面的方法同樣,只不過返回的是該線程調用函數的名字數字 + (NSArray *)callStackSymbols; NSArray* nameNumArray=[NSThread callStackSymbols]; 注意:callStackReturnAddress和callStackSymbols這兩個函數能夠同NSLog聯合使用來跟蹤線程的函數調用狀況,是編程調試的重要手段
隱式建立&線程間通信
如下方法位於NSObject(NSThreadPerformAdditions)分類中,全部繼承自NSObject實例化對象均可以調用如下方法。
/** 指定方法在主線程中執行 參數1. SEL 方法 2.方法參數 3.BOOL類型 表示是否等待當前aSelector方法執行完畢 4.指定的Runloop model */ - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array; - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait; // equivalent to the first method with kCFRunLoopCommonModes /** 指定方法在某個線程中執行 參數1. SEL 方法 2.方法參數 3.是否等待當前執行完畢 4.指定的Runloop model */ - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // equivalent to the first method with kCFRunLoopCommonModes /** 指定方法在開啓的子線程中執行 參數1. SEL 方法 2.方法參數 */ - (void)performSelectorInBackground:(SEL)aSelector withObject:(nullable id)arg API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
注意:咱們提到的線程間通信就是這幾個方法,沒有多高大上多複雜。
再注意:蘋果聲明UI更新必定要在UI線程(主線程)中執行,雖然不是全部後臺線程更新UI都會出錯。
再注意:waitUntilDone後面的這個BOOL類型的參數,這個參數的意義有點像咱們是否同步執行aSelector這個任務!具體的看下面兩張圖的內容就一目瞭然了。