iOS多線程-NSOperation簡單介紹

復(fù)習(xí)下線程的基礎(chǔ)知識, 這里主要是參考文頂頂多線程篇復(fù)習(xí)寫的。

一、NSOperation簡介

1、NSOperation的作用

配合使用NSOperation和NSOperationQueue也能實現(xiàn)多線程編程
(1)先將需要執(zhí)行的操作封裝到一個NSOperation對象中
(2)然后將NSOperation對象添加到NSOperationQueue中
(3)系統(tǒng)會?動將NSOperationQueue中的NSOperation取出來
(4)將取出的NSOperation封裝的操作放到?條新線程中執(zhí)?

2、NSOperation的子類

NSOperation是個抽象類,并不具備封裝操作的能力,必須使?它的子類
使用NSOperation?類的方式有3種:

(1) NSInvocationOperation

//創(chuàng)建NSInvocationOperation對象
- (id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg;

//調(diào)用start方法開始執(zhí)行操作, 一旦執(zhí)行操作,就會調(diào)用target的sel方法
- (void)start;

注意
默認情況下,調(diào)用了start方法后并不會開一條新線程去執(zhí)行操作,而是在當(dāng)前線程同步執(zhí)行操作
只有將NSOperation放到一個NSOperationQueue中,才會異步執(zhí)行操作

代碼示例

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 創(chuàng)建隊列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    // 創(chuàng)建操作
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil];
    // operation直接調(diào)用start,是同步執(zhí)行(在當(dāng)前線程執(zhí)行操作)
//    [operation start];
    // 添加操作到隊列中,會自動異步執(zhí)行
    [queue addOperation:operation];
}

- (void)download {
    NSLog(@"download-----%@", [NSThread currentThread]);
}
@end

(2)NSBlockOperation

創(chuàng)建NSBlockOperation對象

+ (id)blockOperationWithBlock:(void (^)(void))block;

通過addExecutionBlock:方法添加更多的操作

- (void)addExecutionBlock:(void (^)(void))block;

注意:只要NSBlockOperation封裝的操作數(shù) > 1,就會異步執(zhí)行操作

代碼示例

#import "ViewController.h"
@interface ViewController ()
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //創(chuàng)建NSBlockOperation操作對象
    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"NSBlockOperation------%@",[NSThread currentThread]);
    }];
    //開啟執(zhí)行操作 在主線程執(zhí)行
    [operation start];
}

代碼二

#import "ViewController.h"
@interface ViewController ()
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"---下載圖片----1---%@", [NSThread currentThread]);
    }];
    
    [operation addExecutionBlock:^{
        NSLog(@"---下載圖片----2---%@", [NSThread currentThread]);
    }];
    
    [operation addExecutionBlock:^{
        NSLog(@"---下載圖片----3---%@", [NSThread currentThread]);
    }];
    // 任務(wù)數(shù)量 > 1,才會開始異步執(zhí)行
    [operation start];
}

(3)自定義子類繼承NSOperation,實現(xiàn)內(nèi)部相應(yīng)的?法

  • 重寫- (void)main方法,在里面實現(xiàn)想執(zhí)行的任務(wù)

注意點
自己創(chuàng)建自動釋放池(因為如果是異步操作,無法訪問主線程的自動釋放池)
經(jīng)常通過- (BOOL)isCancelled方法檢測操作是否被取消,對取消做出響應(yīng)

3、NSOperationQueue

  • NSOperationQueue的作用
    NSOperation可以調(diào)用start方法來執(zhí)行任務(wù),但默認是同步執(zhí)行的
    如果將NSOperation添加到NSOperationQueue(操作隊列)中,系統(tǒng)會自動異步執(zhí)行NSOperation中的操作

  • 添加操作到NSOperationQueue中

- (void)addOperation:(NSOperation *)op
- (void)addOperationWithBlock:(void (^)(void))block;

代碼示例一:添加操作到主隊列中,操作數(shù)大于0的才開啟另外子線程執(zhí)行

#import "ViewController.h"
@interface ViewController ()
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"---下載圖片----11---%@", [NSThread currentThread]);
    }];
    
    [operation1 addExecutionBlock:^{
        NSLog(@"---下載圖片----12---%@", [NSThread currentThread]);
    }];
    
    NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"---下載圖片----2---%@", [NSThread currentThread]);
    }];
    
    NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"---下載圖片----3---%@", [NSThread currentThread]);
    }];
 
    // 1、主隊列
    NSOperationQueue *queue = [NSOperationQueue mainQueue];
    // 2.添加操作到主隊列中 操作數(shù)大于0的才開啟另外子線程執(zhí)行
    [queue addOperation:operation1];
    [queue addOperation:operation2];
    [queue addOperation:operation3];
}

@end

代碼示例二:添加操作到NSOperationQueue中,自動異步執(zhí)行

#import "ViewController.h"
@interface ViewController ()
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"---下載圖片----11---%@", [NSThread currentThread]);
    }];
    
    [operation1 addExecutionBlock:^{
        NSLog(@"---下載圖片----12---%@", [NSThread currentThread]);
    }];
    
    NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"---下載圖片----2---%@", [NSThread currentThread]);
    }];
    
    NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"---下載圖片----3---%@", [NSThread currentThread]);
    }];
    
    // 1.創(chuàng)建隊列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    // 2.把操作添加到隊列中 自動異步執(zhí)行
    [queue addOperation:operation1];
    [queue addOperation:operation2];
    [queue addOperation:operation3];
}
@end

注意:系統(tǒng)自動將NSOperationqueue中的NSOperation對象取出,將其封裝的操作放到一條新的線程中執(zhí)行。上面的代碼示例中,一共有四個任務(wù),operation1和operation2分別有一個任務(wù),operation3有兩個任務(wù)。一共四個任務(wù),開啟了四條線程。通過任務(wù)執(zhí)行的時間可以看出,這些任務(wù)是并行執(zhí)行的。
提示:隊列的取出是有順序的,與打印結(jié)果并不矛盾。這就好比,選手A,BC雖然起跑的順序是先A,后B,然后C,但是到達終點的順序卻不一定是A,B在前,C在后。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容