NSThread是iOS中底層的線程類,相比GCD和NSOperation更加輕量級(jí),也提供了更為靈活的使用方式,可更直觀地控制線程對(duì)象,但需要管理線程的生命周期、同步、加鎖等問(wèn)題,會(huì)導(dǎo)致一定的性能開銷。
NSThread的精確度比GCD高,可取消該線程執(zhí)行,并且可自定義線程。
創(chuàng)建線程
動(dòng)態(tài)方法
NSThread *aThread = [[NSThread alloc] initWithTarget:self selector:@selector(runThread) object:nil];
aThread.threadPriority = 1; // [0.0~1.0],1.0為最高優(yōu)先級(jí)
[aThread start];
[aThread main]; // thread body method [aThread cancel];
靜態(tài)方法
[NSThread detachNewThreadSelector:@selector(runThread) toTarget:self withObject:nil];
該方法會(huì)立即創(chuàng)建并啟動(dòng)新線程
隱式創(chuàng)建線程
[self performSelectorInBackground:@selector(runThread) withObject:nil];
其他屬性和操作
[NSThread mainThread];
[NSThread currentThread];
[self performSelector:@selector(runThread) withObject:nil]; // 在當(dāng)前線程執(zhí)行操作
[self performSelectorOnMainThread:@selector(runThread) withObject:nil waitUntilDone:YES]; // 在主線程執(zhí)行操作
[self performSelector:@selector(runThread) onThread:thread withObject:nil waitUntilDone:YES]; // 在指定線程上執(zhí)行操作
performSelector
注意:performSelector相關(guān)方法會(huì)創(chuàng)建一個(gè)timer到當(dāng)前線程或指定線程的runloop中,若當(dāng)前線程沒(méi)有runloop,則該performSelector方法會(huì)失效。
因主線程有默認(rèn)的runloop,所以在主線程中執(zhí)行performSelector,則從不會(huì)失效。所以在異步線程中要稍微注意。
不過(guò),performSelector方法在Swift中已棄用,因其在ARC下不安全。
原因在于:ARC為了確保參數(shù)在方法運(yùn)行期間的存在,會(huì)將輸入?yún)?shù)在方法開始時(shí)先進(jìn)行retain,在最后release,而performSelector并沒(méi)有機(jī)會(huì)為被調(diào)用的selector方法指定參數(shù),所以被調(diào)用的selector方法的輸入?yún)?shù)可能會(huì)指向未知的內(nèi)存地址,導(dǎo)致crash。
線程鎖
NSCondition是鎖對(duì)象,可用于保護(hù)當(dāng)前訪問(wèn)的資源。
NSCondition *lock = [[NSCondition alloc] init];
[lock lock];
// 線程中執(zhí)行操作
[lock unLock];
自定義線程
NSThread可以做到自定義線程,如下的Swift代碼,定義了CSThread類,繼承自NSThread。
添加delegate屬性,并重寫其main()方法,在其中即可指定線程內(nèi)執(zhí)行的任務(wù).
import UIKit
protocol CSThreadCompletionDelegate {
func csThreadCompletion()
}
class CSThread: NSThread {
var delegate: CSThreadCompletionDelegate!
override func main() {
super.main()
sleep(2)
dispatch_async(dispatch_get_main_queue(), { () -> Void in
if (self.delegate != nil) {
self.delegate.csThreadCompletion()
}
})
}
}
使用如下,
let csThread = CSThread()
csThread.delegate = selfcsThread.start()
// MARK: - CSThreadCompletionDelegate
func csThreadCompletion() {
print("csThreadCompletion")
}