你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS 多線程詳解 NSThread, NSOperationQueue(NSInvocationOperation, NSBlockOperation), GCD

iOS 多線程詳解 NSThread, NSOperationQueue(NSInvocationOperation, NSBlockOperation), GCD

編輯:IOS開發綜合
    //進程: 程序在計算機的一次執行活動, 一個程序就是一個進程, 在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

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved