NSThread是輕量級(jí)的多線程開(kāi)發(fā),OC語(yǔ)言編寫(xiě),更加面向?qū)ο?,使用起?lái)也并不復(fù)雜,但是使用NSThread需要自己管理線程生命周期。在iOS開(kāi)發(fā)中很少使用它來(lái)創(chuàng)建一個(gè)線程,但是經(jīng)常使用它做一些延時(shí)操作,獲取當(dāng)前線程,線程間通訊等等。
但是,在線程同步方面,控制線程執(zhí)行順序比較麻煩,線程同步對(duì)數(shù)據(jù)的加鎖會(huì)有一定的系統(tǒng)開(kāi)銷,且創(chuàng)建線程也會(huì)增加系統(tǒng)的開(kāi)銷。
1 創(chuàng)建方法
有多種創(chuàng)建方法,- (void)runDemo:(NSString *)param;為要執(zhí)行的示例方法。
- (void)runDemo:(NSString *)param { NSThread *current = [NSThread currentThread]; NSLog(@"%@---%@ is running", param, current);}/// 方式1 自動(dòng)創(chuàng)建線程, 并且自動(dòng)啟動(dòng)- (void)threadCreateOne { // 在另一個(gè)線程執(zhí)行 runDemo: [self performSelectorInBackground:@selector(runDemo:) withObject:@"One"];}/// 方式2 創(chuàng)建完線程直接(自動(dòng))啟動(dòng)- (void)threadCreateTwo { [NSThread detachNewThreadSelector:@selector(runDemo:) toTarget:self withObject:@"Two"];}/// 方式3 先創(chuàng)建初始化線程,然后start開(kāi)啟線程- (void)threadCreateThree { NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(runDemo:) object:@"Three"]; // 可以設(shè)置線程名字 thread.name = @"名字"; // 開(kāi)啟線程 [thread start];}
下面為測(cè)試代碼,以及打印結(jié)果,我們調(diào)用的順序是One->Two->Three,但是打印結(jié)果是Two->Three->One,因?yàn)榫€程啟動(dòng)后僅僅處于就緒狀態(tài),實(shí)際是否執(zhí)行要由CPU根據(jù)當(dāng)前狀態(tài)調(diào)度,即執(zhí)行順序是無(wú)序的,這也是多線程的特點(diǎn)。
/// 點(diǎn)擊屏幕后創(chuàng)建線程- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ [self threadCreateOne]; [self threadCreateTwo]; [self threadCreateThree];}打印結(jié)果: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 常用函數(shù)
獲取當(dāng)前線程,獲取主線程,判斷當(dāng)前線程是否為主線程。
// 獲取當(dāng)前線程NSThread *current = [NSThread currentThread];// 獲取主線程current = [NSThread mainThread];// 判斷當(dāng)前線程是否為主線程BOOL isMain = [current isMainThread];
暫停線程,下面代碼為2種方法均讓當(dāng)前線程睡5s
[NSThread sleepForTimeInterval:5];NSDate *date = [NSDate dateWithTimeInterval:5 sinceDate:[NSDate date]];[NSThread sleepUntilDate:date];
獲取線程的狀態(tài),分別為:正在執(zhí)行、已經(jīng)完成、已經(jīng)取消。
@PRoperty (readonly, getter=isExecuting) BOOL executing;@property (readonly, getter=isFinished) BOOL finished;@property (readonly, getter=isCancelled) BOOL cancelled;
在指定的線程(已存在的線程)、主線程、當(dāng)前線程上執(zhí)行方法。這種比較常用,通常用于線程間通訊,且它們是NSObject的擴(kuò)展方法,使用起來(lái)很方便。
// 在指定的線程執(zhí)行runDemo:方法,最后的YES代表:下面的代碼會(huì)阻塞,等runDemo:方法在thread線程執(zhí)行完畢后,才會(huì)執(zhí)行下面代碼的下一行代碼,設(shè)為NO則不阻塞。那么runDemo:與下一行代碼的執(zhí)行順序不確定[self performSelector:@selector(runDemo:) onThread:thread withObject:nil waitUntilDone:YES];// 在主線程執(zhí)行runDemo:方法,YES參數(shù)同上[self performSelectorOnMainThread:@selector(runDemo:) withObject:nil waitUntilDone:YES];// 在當(dāng)前線程執(zhí)行方法[self performSelector:@selector(run) withObject:nil];
退出線程
+ (void)exit;
線程優(yōu)先級(jí)相關(guān),優(yōu)先級(jí)范圍是0.0 ~ 1.0,默認(rèn)0.5,值越大,優(yōu)先級(jí)越高。開(kāi)發(fā)時(shí),很少使用優(yōu)先級(jí),如果設(shè)置優(yōu)先級(jí)且使用線程鎖會(huì)造成優(yōu)先級(jí)翻轉(zhuǎn),需要特備注意。
+ (double)threadPriority;+ (BOOL)setThreadPriority:(double)p;
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注