復(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在后。