標籤:style color 使用 os io 檔案 資料 for
面試官:你給我講講多線程吧。
我:多線程,就是多線程唄。。。
要是都這麼回答,還有多少人要你。
=====================================================
首先分析多線程的使用環境:
多執行緒包括Core Data的多線程訪問,UI的並行繪製,非同步網路請求以及一些在運行態記憶體吃緊的情況下處理大檔案的方案等。
其次,分別舉例說明iOS提供的多線程的實現方法
iOS中提供了以下集中中多線程的實現方式
1.NSOBjcet實現
// 最簡單的多線程 執行方式 // 參數1:需要在後台(子線程)執行方法 // 參數2:給這個方法傳參 [self performSelectorInBackground:@selector(btnUpClicked:)withObject:nil];
2.NSThread實現
// 優點:在所有的多線程實現方式中 最輕量級// 可以按照需求 任意控制thread對象 即:線程的加鎖等操作// 缺點:控制太繁瑣 不能自己控制安全執行緒 // NSThread 的一個對象 就代表一個線程 NSThread *thread = [[NSThread alloc]initWithTarget:selfselector:@selector(btnUpClicked:)object:nil]; [thread start]; [thread release];
3.NSOperation實現
// NSOperation代表一個任務 自己不能實現多線程// NSOperation是一個抽象類別 不能直接使用 需要建立一個子類去編寫實現的內容// 任務開始 會在當前線程執行任務(main方法中的代碼) MyOperation *operation = [[MyOperation alloc] init]; [operation start]; [operation release]; // 系統已經寫好了兩個類 可以直接使用// NSInvocationOperation *invocation = [[NSInvocationOperation alloc] initWithTarget:<#(id)#> selector:<#(SEL)#> object:<#(id)#>] NSBlockOperation *block = [NSBlockOperation blockOperationWithBlock:^{ // 填寫你要執行的任務內容 }];
@implementation MyOperation- (void)main{ // operation在main方法中寫要執行的任務 static int count = 0 ; for (int i = 0 ; i < 600000000; i ++) { count ++; } NSLog(@"%d", count); // 判斷當前任務是否為主線程 0為不是 1為是 BOOL b = [NSThread isMainThread]; NSLog(@"%d", b); NSThread *thread = [NSThread currentThread]; NSLog(@"當前線程為:%@", thread); }@end 4.NSOperationQueue
// 任務隊列(NSOperationQueue) 內部管理一些列的線程 MyOperation *op1 = [[MyOperation alloc] init]; MyOperation *op2 = [[MyOperation alloc] init]; MyOperation *op3 = [[MyOperation alloc] init]; MyOperation *op4 = [[MyOperation alloc] init]; NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 設定最大並發數 [queue setMaxConcurrentOperationCount:2]; [queue addOperation:op1]; [queue addOperation:op2]; [queue addOperation:op3]; [queue addOperation:op4]; // 優點:能夠自己管理 安全執行緒 能夠合理的安排線程 降低系統的開銷 提高對線程的利用率 // 缺點:可讀性差 寫起來比較繁瑣
5.GCD
// GCD 是基於隊列的 多線程實現方式 // 隊列的類型 // 1.並行: 多個任務同時執行 Concurrent // 2.串列: 依次執行任務(同一事件只執行一個任務) Serial // 自己建立一個隊列 // 參數1:給隊列起個名字 // 參數2:選擇隊列的類型 DISPATCH_QUEUE_CONCURRENT(串列) dispatch_queue_attr_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT); // 使用隊列 // 參數1: 在哪個隊列執行代碼 // 參數2: 要執行的代碼 dispatch_async(queue, ^{ [self btnUpClicked:nil]; }); 進階用法:
// 系統定義了5個隊列 // 1. 一個串列隊列 主隊列作用 : 管理主線程的相關事務 // 獲得主隊列 dispatch_queue_t mainQueue = dispatch_get_main_queue(); // 在主隊列執行任務// dispatch_async(mainQueue, ^{// [self btnUpClicked:nil];// }); // 2. 4個並行隊列 (並行隊列) // 參數1: 選擇隊列的優先順序 // 參數2: 給未來使用 一般填0 dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);// dispatch_async(globalQueue, ^{// [self btnUpClicked:nil];// }); // 高端使用 // 1.全域隊列擷取資料 回到主隊列將資料載入到視圖上// dispatch_async(globalQueue, ^{// // // 全域隊列(子線程)擷取資料// NSString *str = @"htt://www.baidu.com";// NSURL *url = [NSURL URLWithString:str];// // NSData *data = [NSData dataWithContentsOfURL:url];// UIImage *image = [UIImage imageWithData:data];// // // 返回主線程 載入UI/更新UI// dispatch_async(mainQueue, ^{// // UIImageView *imageView = [[UIImageView alloc] init];// // 給視圖賦值// imageView.image = image;// // });// }); // 2.一段代碼只執行依次 // 大部分的時候 都在單例方法中使用 static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSLog(@"只執行依次"); }); // 3.一段代碼執行多次 (全域隊列有效) // 參數1: 執行多少次 // 參數2: 在哪個隊列有效 // 參數3: 要執行的內容 dispatch_apply(4, globalQueue, ^(size_t a) { NSLog(@"%zu", a); }); // 4.定時 // 參數1: 間隔幾秒 // 參數2: 執行的內容 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSLog(@"====="); });
強烈建議用GCD去嚇唬人。這可不是我說的,是他們總結的,反正好用就是個,尤其是遇到面試官不是iOS開發的。。。左拉有扯地拉他回GCD。一句話GCD萬歲~