//進程: 程序在計算機的一次執行活動, 一個程序就是一個進程, 在iOS中, 一個app就是一個進程 //線程: 程序執行的最小單元, 一個進程中至少有一個線程(主線程) //線程中要注意的幾點:1 線程中的autorelease對象不能釋放, 必須手動釋放或者添加自動釋放池 2 子線程中刷新UI可能失敗(在子線程中不要刷新UI) //隊列:先進先出 //棧:先進後出 //隊列裡涉及到串行, 並行. //串行: 一次只能執行一個任務 //並行: 一次可以執行多個任務 //多線程使用會增加效率, 但是會增加開銷 //當多個線程訪問同一個資源時, 會出現搶占資源的情況, 需要加一個鎖(NSLock) // // FirstVC.m // LessonThread // // Created by lanouhn on 14-9-18. // Copyright (c) 2014年 [email protected] 陳聰雷. All rights reserved. // #import "FirstVC.h" @interface FirstVC () @end @implementation FirstVC - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(animation) userInfo:nil repeats:YES]; //進程: 程序在計算機的一次執行活動, 一個程序就是一個進程, 在iOS中, 一個app就是一個進程 //線程: 程序執行的最小單元, 一個進程中至少有一個線程(主線程) } - (void)animation { [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:0.1]; [UIView setAnimationBeginsFromCurrentState:YES]; //參數1: 現在視圖的角度, 參數2: 將要改變的角度, 參數3, 4, 5, 是否改變X, Y, Z軸 self.windmillImageView.layer.transform = CATransform3DRotate(self.windmillImageView.layer.transform, M_PI_4, 0, 0, 1); } - (IBAction)banZhuan { for (int i = 0; i < 100; i++) { NSLog(@"搬了%d塊轉", i + 1); } } - (IBAction)banZhuanPro:(id)sender { //通過NSObject的方法初始化線程 //performSelectorInBackground:<#(SEL)#> withObject:<#(id)#> 會自動開辟一個後台線程, SEL:在這個後台線程中執行的方法, id: 用於傳遞參數 [self performSelectorInBackground:@selector(banZhuanPlus) withObject:nil]; } - (IBAction)banZhuanWithThread:(id)sender { //通過NSThread創建線程, 參數1: 方法的執行者, 參數2: 在線程中執行的方法, 參數3: 用於傳遞參數 //1 創建線程 NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(banZhuanPlus) object:nil]; //2 在主線程執行 [thread start]; [thread release]; } - (IBAction)banZhuanWithNSOperationQueue:(id)sender { //NSOperation操作單元, 用來執行方法, 是一個抽象的類, 必須子類化或者使用系統創建好的子類:NSInvocationOperation, NSBlockOperation. NSOperation是最小的操作單元, 只能夠執行一次 //NSInvocationOperation創建 //1 創建 NSInvocationOperation *invocation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(banZhuanPlus) object:nil]; //2 執行 // [invocation start]; //NSBlockOperation創建 //1 創建 NSBlockOperation *block = [NSBlockOperation blockOperationWithBlock:^{ [self banZhuanPlus]; }]; //2 執行 // [block start]; //這個隊列會自動創建一個輔助線程, 裡面只能添加NSOperation的對象以及子類的對象 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; //設置最大並行數 [queue setMaxConcurrentOperationCount:2]; //只要把操作單元添加到隊列中就會執行, 上面無需start [queue addOperation:block]; [queue addOperation:invocation]; //隊列:先進先出 //棧:先進後出 //隊列裡涉及到串行, 並行. //串行: 一次只能執行一個任務 //並行: 一次可以執行多個任務 [queue release]; [invocation release]; } - (IBAction)banZhuanWithGCD:(id)sender { //GCD:Grand Central Dispatch 大中央調度 是Apple推崇的多線程管理策略 是通過隊列對多線程進行管理的 //第1中隊列 主調隊列, 在主線程中執行, 並且是串行(一次操作一個) dispatch_queue_t mainQueue = dispatch_get_main_queue(); //第二種隊列 全局隊列, 在子線程中執行, 並且是並行(一次可以執行多個) //參數1: 設置隊列的優先級(high, default, low, background) //參數2: 是預留參數, 未來使用 dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //第三種隊列 自定義隊列 在子線程中執行, 可以設置並行或者串行 //參數1: 區分隊列的唯一標示, 是一個可選項, 若不寫, 寫:NULL, 若寫, 規范的例子是: "com.example.myqueue" //參數2: 設置並行或串行得 //串行: DISPATCH_QUEUE_SERIAL //並行: DISPATCH_QUEUE_CONCURRENT dispatch_queue_t customQueue = dispatch_queue_create("com.example.myqueue", DISPATCH_QUEUE_CONCURRENT); NSLog(@"%@ %@ %@", mainQueue, globalQueue, customQueue); //同步執行(需要等待執行完畢) //參數1: 指定隊列 參數2: Block, 執行的操作 dispatch_sync(globalQueue, ^{ [self banZhuanPlus]; }); //異步執行(無需等待) //參數1: 指定隊列 參數2: Block, 執行的操作 dispatch_async(globalQueue, ^{ [self banZhuanPlus]; }); //延遲執行 // dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#delayInSeconds#> * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ // <#code to be executed after a specified delay#> // }); } - (void)banZhuanPlus { //線程中要注意的幾點:1 線程中的autorelease對象不能釋放, 必須手動釋放或者添加自動釋放池 2 子線程中刷新UI可能失敗(在子線程中不要刷新UI) @autoreleasepool { for (int i = 0; i < 100; i++) { NSLog(@"搬了%d塊轉", i + 1); } } //不要這樣寫 // self.view.backgroundColor = [UIColor redColor]; //應該這樣寫, 在主線程中刷新UI [self performSelectorOnMainThread:@selector(refreshUI) withObject:nil waitUntilDone:YES]; } - (void)refreshUI { self.view.backgroundColor = [UIColor redColor]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (void)dealloc { [_windmillImageView release]; [super dealloc]; } @end