iOS多線程實現2-NSThread,ios2-nsthread
NSThread是輕量級的多線程開發,OC語言編寫,更加物件導向,使用起來也並不複雜,但是使用NSThread需要自己管理線程生命週期。在iOS開發中很少使用它來建立一個線程,但是經常使用它做一些延時操作,擷取當前線程,線程間通訊等等。
但是,線上程同步方面,控制線程執行順序比較麻煩,線程同步對資料的加鎖會有一定的系統開銷,且建立線程也會增加系統的開銷。
1 建立方法
有多種建立方法,- (void)runDemo:(NSString *)param;為要執行的樣本方法。
- (void)runDemo:(NSString *)param { NSThread *current = [NSThread currentThread]; NSLog(@"%@---%@ is running", param, current);}/// 方式1 自動建立線程, 並且自動啟動- (void)threadCreateOne { // 在另一個線程執行 runDemo: [self performSelectorInBackground:@selector(runDemo:) withObject:@"One"];}/// 方式2 建立完線程直接(自動)啟動- (void)threadCreateTwo { [NSThread detachNewThreadSelector:@selector(runDemo:) toTarget:self withObject:@"Two"];}/// 方式3 先建立初始化線程,然後start開啟線程- (void)threadCreateThree { NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(runDemo:) object:@"Three"]; // 可以設定線程名字 thread.name = @"名字"; // 開啟線程 [thread start];}
下面為測試代碼,以及列印結果,我們調用的順序是One->Two->Three,但是列印結果是Two->Three->One,因為線程啟動後僅僅處於就緒狀態,實際是否執行要由CPU根據目前狀態調度,即執行順序是無序的,這也是多線程的特點。
/// 點擊螢幕後建立線程- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ [self threadCreateOne]; [self threadCreateTwo]; [self threadCreateThree];}列印結果:2015-08-27 16:27:34.974 01test[1183:76667] Two---<NSThread: 0x7ff250e1c9a0>{number = 3, name = (null)} is running2015-08-27 16:27:34.974 01test[1183:76668] Three---<NSThread: 0x7ff250e168a0>{number = 4, name = 名字} is running2015-08-27 16:27:34.974 01test[1183:76666] One---<NSThread: 0x7ff250f406a0>{number = 2, name = (null)} is running
2 常用函數
擷取當前線程,擷取主線程,判斷當前線程是否為主線程。
// 擷取當前線程NSThread *current = [NSThread currentThread];// 擷取主線程current = [NSThread mainThread];// 判斷當前線程是否為主線程BOOL isMain = [current isMainThread];
暫停線程,下面代碼為2種方法均讓當前線程睡5s
[NSThread sleepForTimeInterval:5];NSDate *date = [NSDate dateWithTimeInterval:5 sinceDate:[NSDate date]];[NSThread sleepUntilDate:date];
擷取線程的狀態,分別為:正在執行、已經完成、已經取消。
@property (readonly, getter=isExecuting) BOOL executing;@property (readonly, getter=isFinished) BOOL finished;@property (readonly, getter=isCancelled) BOOL cancelled;
在指定的線程(已存在的線程)、主線程、當前線程上執行方法。這種比較常用,通常用於線程間通訊,且它們是NSObject的擴充方法,使用起來很方便。
// 在指定的線程執行runDemo:方法,最後的YES代表:下面的代碼會阻塞,等runDemo:方法在thread線程執行完畢後,才會執行下面代碼的下一行代碼,設為NO則不阻塞。那麼runDemo:與下一行代碼的執行順序不確定[self performSelector:@selector(runDemo:) onThread:thread withObject:nil waitUntilDone:YES];// 在主線程執行runDemo:方法,YES參數同上[self performSelectorOnMainThread:@selector(runDemo:) withObject:nil waitUntilDone:YES];// 在當前線程執行方法[self performSelector:@selector(run) withObject:nil];
退出線程
+ (void)exit;
線程優先順序相關,優先順序範圍是0.0 ~ 1.0,預設0.5,值越大,優先順序越高。開發時,很少使用優先順序,如果設定優先權且使用線程鎖會造成優先順序翻轉,需要特備忘意。
+ (double)threadPriority;+ (BOOL)setThreadPriority:(double)p;