iOS學習41之多線程,ios41多線程
1. 多線程概述 1> 程式、進程和進程的概念
程式:由原始碼產生的可執行應用。(例如:QQ.app)
進程:一個正在啟動並執行程式可以看做一個進程。(例如:正在啟動並執行QQ就是一個進程),進程擁有獨立運行所需的全部資源。
線程:程式中獨立啟動並執行程式碼片段。(例如:接收QQ訊息的代碼)
一個進程是由一或多個線程組成。進程只負責資源的調度和分配,線程才是程式真正的執行單元,負責代碼的執行。
2> 單線程
每個正在啟動並執行程式(即進程),至少包含一個線程,這個線程叫主線程。
主線程在程式啟動時被建立,用於執行main函數。
只有一個主線程的程式,稱作單線程程式。
在單線程程式中,主線程負責執行程式的所有代碼(UI展現以及重新整理,網路請求,本機存放區等等)。這些代碼只能順序執行,無法並發執行。
3> 多線程
4> 單線程和多線程區別
單線程程式:只有一個線程,即主線程,代碼順序執行,容易出現代碼阻塞(頁面假死)。
多線程程式:有多個線程,線程間獨立運行,能有效避免代碼阻塞,並且提高程式的運行效能。
注意:iOS中關於UI的添加和重新整理必須在主線程中操作。
2. NSThread與NSObject建立多線程 1> NSThread建立方法
// 參數1:target // 參數2:方法 // 參數3:傳遞的參數 NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(sayHi) object:nil]; // 開啟線程 [thread start];
// 線程自動開啟 [NSThread detachNewThreadSelector:@selector(sayHi) toTarget:self withObject:nil];
2> NSThread其他常用屬性和方法
標頭檔中其他常用屬性和方法的聲明:
// 擷取當前的線程+ (NSThread *)currentThread;// 主線程休眠ti秒+ (void)sleepForTimeInterval:(NSTimeInterval)ti;// 直接將線程退出+ (void)exit;// 判斷是否為主線程+ (BOOL)isMainThread;// 擷取主線程+ (NSThread *)mainThread;// 取消線程,不是真正的取消,只是給線程發送一個訊號,通過這份訊號進行取消- (void)cancel;// 手動開闢子線程時啟動線程- (void)start;
代碼:
// 擷取當前線程 NSLog(@"currentThread == %@", [NSThread currentThread]); // 擷取主線程 NSLog(@"mainThread == %@", [NSThread mainThread]); // 判斷當前線程是否為主線程 NSLog(@"isMainThread == %d", [NSThread isMainThread]);
3> NSObject開啟子線程
- (void)viewDidLoad { [super viewDidLoad]; // 使用performSelectorInBackground開闢子線程 // 參數1:selector // 參數2:方法傳遞的參數 [self performSelectorInBackground:@selector(sayHi) withObject:nil]; self.view.backgroundColor = [UIColor yellowColor];}// 子線程執行方法- (void)sayHi{ NSLog(@"Hello World"); NSLog(@"currentThread == %@", [NSThread currentThread]); NSLog(@"mainThread == %@", [NSThread mainThread]); // 回到主線程修改當前背景顏色 // 參數1:selector // 參數2:傳的參數 // 參數3:是否等待子線程執行完成之後進入主線程 [self performSelectorOnMainThread:@selector(mainThreadChangeColor) withObject:nil waitUntilDone:YES];}// 主線程執行方法- (void)mainThreadChangeColor{ self.view.backgroundColor = [UIColor cyanColor]; NSLog(@"currentThread == %@", [NSThread currentThread]); NSLog(@"mainThread == %@", [NSThread mainThread]);}
4> 線程結束
使用NSThread和NSObject實現的開闢線程,系統會自動釋放,關不關都可以
結束線程的兩種方式:
// 取消線程 [thread cancel]; // 不是真正的取消,只是給線程發送一個訊號,通過這份訊號進行取消 // 直接將線程退出 [NSThread exit];
3. NSOperationQueue 1> 概述
NSOperation類,在MVC中屬於M,是用來封裝單個任務相關的代碼和資料的抽象類別
因為它是抽象的,不能夠直接使用這個類,而是使用子類( NSInvocationOperation或NSBlockOperation )來執行實際任務。
NSOperation(含子類),只是一個操作,本身無主線程、子線程之分,可在任意線程中使用。通常與NSOperationQueue結合使用。
2> NSInvocationOperation
NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(test) object:nil]; // 在單獨使用NSOperation的子類去建立線程的時候,一定要啟動才行 [invocationOperation start];- (void)test{ NSLog(@"