一、NSOperation簡介
1、簡單說明
- NSOperation的作?:配合使用NSOperation和NSOperationQueue也能實(shí)現(xiàn)多線程編程
- NSOperation和NSOperationQueue實(shí)現(xiàn)多線程的具體步驟:
(1)先將需要執(zhí)行的操作封裝到一個NSOperation對象中
(2)然后將NSOperation對象添加到NSOperationQueue中
(3)系統(tǒng)會?動將NSOperationQueue中的NSOperation取出來
(4)將取出的NSOperation封裝的操作放到?條新線程中執(zhí)?
2、NSOperation的子類
- NSOperation是個抽象類,并不具備封裝操作的能力,必須使?它的子類
- 使用NSOperation?類的方式有3種:
(1)NSInvocationOperation
(2)NSBlockOperation
(3)自定義子類繼承NSOperation,實(shí)現(xiàn)內(nèi)部相應(yīng)的?法
3、執(zhí)行
執(zhí)行一個operation有兩種方:
- 第一種是自己手動的調(diào)用start這個方法,這種方法調(diào)用會在當(dāng)前調(diào)用的線程進(jìn)行同步執(zhí)行,所以在主線程里面自己一定要小心的調(diào)用,不然就會把主線程給卡死,還不如直接用GCD呢。
- 第二種是將operation添加到operationQueue中去,這個也是我們用得最多的也是提倡的方法。NSOperationQueue會在我們添加進(jìn)去operation的時候盡快進(jìn)行執(zhí)行。當(dāng)然如果NSOperationQueue的maxConcurrentOperationCount如果設(shè)置為1的話,進(jìn)相當(dāng)于FIFO了。
二、 操作
1、NSInvocationOperation子類
注意:操作對象默認(rèn)在主線程中執(zhí)行,只有添加到隊列中才會開啟新的線程。即默認(rèn)情況下,如果操作沒有放到隊列中queue中,都是同步執(zhí)行。只有將NSOperation放到一個NSOperationQueue中,才會異步執(zhí)行操作
1.1 創(chuàng)建并執(zhí)行操作
NSInvocationOperation *operation=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil];
[operation start];//開始執(zhí)行任務(wù)(同步執(zhí)行)
1.2 事件響應(yīng)
- (void)run {
NSLog(@"%@",[NSThread currentThread]);
}
1.3 執(zhí)行結(jié)果
**2016-07-06 10:15:32.593 ****類庫****[6716:2832599] <NSThread: 0x166456b0>{number = 1, name = main}**
2、NSBlockOperation子類
2.1 創(chuàng)建并執(zhí)行操作
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^(){
NSLog(@"執(zhí)行了一個新的操作,線程:%@", [NSThread currentThread]);
}];
// 開始執(zhí)行任務(wù)(這里還是同步執(zhí)行)
[operation start];
2.2.通過addExecutionBlock方法添加block操作
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^(){
NSLog(@"執(zhí)行第1次操作,線程:%@", [NSThread currentThread]);
}];
[operation addExecutionBlock:^() {
NSLog(@"又執(zhí)行了1個新的操作,線程:%@", [NSThread currentThread]);
}];
[operation addExecutionBlock:^() {
NSLog(@"又執(zhí)行了1個新的操作,線程:%@", [NSThread currentThread]);
}];
[operation addExecutionBlock:^() {
NSLog(@"又執(zhí)行了1個新的操作,線程:%@", [NSThread currentThread]);
}];
// 開始執(zhí)行任務(wù)
[operation start];
結(jié)果
**2016-07-06 10:28:12.476 ****類庫****[6730:2835101] 2****又執(zhí)行了****1****個新的操作,線程:****<NSThread: 0x17d3ca10>{number = 2, name = (null)}**
**2016-07-06 10:28:12.476 ****類庫****[6730:2835035] 1****執(zhí)行第****1****次操作,線程:****<NSThread: 0x17d19150>{number = 1, name = main}**
**2016-07-06 10:28:12.477 ****類庫****[6730:2835101] 3****又執(zhí)行了****1****個新的操作,線程:****<NSThread: 0x17d3ca10>{number = 2, name = (null)}**
**2016-07-06 10:28:12.477 ****類庫****[6730:2835035] 4****又執(zhí)行了****1****個新的操作,線程:****<NSThread: 0x17d19150>{number = 1, name = main}**
可以看出,這4個block是并發(fā)執(zhí)行的,也就是在不同線程中執(zhí)行的
3、NSOperationQueue
NSOperationQueue的作?:
(1) NSOperation可以調(diào)?start?法來執(zhí)?任務(wù),但默認(rèn)是同步執(zhí)行的
(2) 如果將NSOperation添加到NSOperationQueue(操作隊列)中,系統(tǒng)會自動異步執(zhí)行NSOperation中的操作
(3) 添加操作到NSOperationQueue中,自動執(zhí)行操作,自動開啟線程
3.1 創(chuàng)建隊列
NSOperationQueue * queue = [[NSOperationQueue alloc] init];
3.2 將操作添加到隊列當(dāng)中
//第一種方式
[queue addOperation:operation1];
//第二種方式
[queue addOperationWithBlock:^{
NSLog(@"NSBlockOperation%@",[NSThread currentThread]);
}];
3.3 示例
NSOperationQueue * queue = [[NSOperationQueue alloc] init];
NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil];
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^(){
NSLog(@"2:NSBlockOperation:%@", [NSThread currentThread]);
}];
[operation2 addExecutionBlock:^() {
NSLog(@"3:NSBlockOperation:%@", [NSThread currentThread]);
}];
[operation2 addExecutionBlock:^() {
NSLog(@"4:NSBlockOperation:%@", [NSThread currentThread]);
}];
[operation2 addExecutionBlock:^() {
NSLog(@"5:NSBlockOperation:%@", [NSThread currentThread]);
}];
[queue addOperation:operation1];
[queue addOperation:operation2];
- (void)run {
NSLog(@"1:NSInvocationOperation:%@", [NSThread currentThread]);
}
結(jié)果:
**2016-07-06 11:03:15.197 ****類庫****[6736:2840181] 1:NSInvocationOperation****:****<NSThread: 0x16542de0>{number = 2, name = (null)}**
**2016-07-06 11:03:15.198 ****類庫****[6736:2840176] 2:NSBlockOperation****:****<NSThread: 0x16521a80>{number = 3, name = (null)}**
**2016-07-06 11:03:15.198 ****類庫****[6736:2840176] 3:NSBlockOperation****:****<NSThread: 0x16521a80>{number = 3, name = (null)}**
**2016-07-06 11:03:15.198 ****類庫****[6736:2840176] 4:NSBlockOperation****:****<NSThread: 0x16521a80>{number = 3, name = (null)}**
**2016-07-06 11:03:15.200 ****類庫****[6736:2840176] 5:NSBlockOperation****:****<NSThread: 0x16521a80>{number = 3, name = (null)}**
可以看出任務(wù)是異步并發(fā)執(zhí)行的