你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS多線程運用開辟中應用NSOperation類的根本辦法

iOS多線程運用開辟中應用NSOperation類的根本辦法

編輯:IOS開發綜合

1、NSOperation簡介

1.簡略解釋

NSOperation的作⽤:合營應用NSOperation和NSOperationQueue也能完成多線程編程

NSOperation和NSOperationQueue完成多線程的詳細步調:

(1)先將須要履行的操作封裝到一個NSOperation對象中

(2)然後將NSOperation對象添加到NSOperationQueue中

(3)體系會⾃動將NSOperationQueue中的NSOperation掏出來

(4)將掏出的NSOperation封裝的操作放到⼀條新線程中執⾏

 2.NSOperation的子類

NSOperation是個籠統類,其實不具有封裝操作的才能,必需使⽤它的子類

應用NSOperation⼦類的方法有3種:

(1)NSInvocationOperation

(2)NSBlockOperation

(3)自界說子類繼續NSOperation,完成外部響應的⽅法

2、 詳細解釋

1.NSInvocationOperation子類

創立對象和履行操作:

//創立操尴尬刁難象,封裝要履行的義務
    //NSInvocationOperation   封裝操作
    NSInvocationOperation *operation=[[NSInvocationOperation alloc]initWithtarget:self selector:@selector(test) object:nil];
   
    //履行操作
    [operation start];

解釋:一旦執⾏操作,就會挪用target的test辦法

代碼示例:

//
//  YYViewController.m
//  01-NSOperation根本1
//
//  Created by 孔醫己 on 14-6-25.
//  Copyright (c) 2014年 itcast. All rights reserved.
//

#import "YYViewController.h"

@interface YYViewController ()

@end


@implementation YYViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
   
    //NSOperation:籠統類,不具有封裝功效
   
    //創立操尴尬刁難象,封裝要履行的義務
    //NSInvocationOperation   封裝操作
    NSInvocationOperation *operation=[[NSInvocationOperation alloc]initWithtarget:self selector:@selector(test) object:nil];
   
    //履行操作
    [operation start];

}

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

打印檢查:

2015111391700829.png (797×26)

留意:操尴尬刁難象默許在主線程中履行,只要添加到隊列中才會開啟新的線程。即默許情形下,假如操作沒有放到隊列中queue中,都是同步履行。只要將NSOperation放到一個NSOperationQueue中,才會異步履行操作

2.NSBlockOperation子類

創立對象和添加操作:

//創立NSBlockOperation操尴尬刁難象
    NSBlockOperation *operation=[NSBlockOperation blockOperationWithBlock:^{
        //......
    }];
   
    //添加操作
    [operation addExecutionBlock:^{
        //....
    }];

代碼示例:

代碼1:

//
//  YYViewController.m
//  02-NSTherad根本2
//
//  Created by 孔醫己 on 14-6-25.
//  Copyright (c) 2014年 itcast. All rights reserved.
//

#import "YYViewController.h"

@interface YYViewController ()

@end


@implementation YYViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
   
    //創立NSBlockOperation操尴尬刁難象
    NSBlockOperation *operation=[NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"NSBlockOperation------%@",[NSThread currentThread]);
    }];
   
   
    //開啟履行操作
    [operation start];
}
@end

打印檢查:

https://www.ios5.online/ios/UploadFiles_8070/201703/2017031615443849.png (812×26)

代碼2:

//
//  YYViewController.m
//  02-NSTherad根本2
//
//  Created by 孔醫己 on 14-6-25.
//  Copyright (c) 2014年 itcast. All rights reserved.
//

#import "YYViewController.h"

@interface YYViewController ()

@end


@implementation YYViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
   
    //創立NSBlockOperation操尴尬刁難象
    NSBlockOperation *operation=[NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"NSBlockOperation------%@",[NSThread currentThread]);
    }];
   
    //添加操作
    [operation addExecutionBlock:^{
        NSLog(@"NSBlockOperation1------%@",[NSThread currentThread]);
    }];
   
    [operation addExecutionBlock:^{
        NSLog(@"NSBlockOperation2------%@",[NSThread currentThread]);
    }];
   
    //開啟履行操作
    [operation start];
}
@end

https://www.ios5.online/ios/UploadFiles_8070/201703/2017031615443853.png (820×63)

留意:只需NSBlockOperation封裝的操作數 > 1,就會異步履行操作

3.NSOperationQueue

NSOperationQueue的作⽤:NSOperation可以調⽤start⽅法來執⾏義務,但默許是同步履行的

假如將NSOperation添加到NSOperationQueue(操作隊列)中,體系會主動異步履行NSOperation中的操作

添加操作到NSOperationQueue中,主動履行操作,主動開啟線程

//創立NSOperationQueue
    NSOperationQueue * queue=[[NSOperationQueue alloc]init];
    //把操作添加到隊列中
    //第一種方法
    [queue addOperation:operation1];
    [queue addOperation:operation2];
    [queue addOperation:operation3];
    //第二種方法
    [queue addOperationWithBlock:^{
        NSLog(@"NSBlockOperation3--4----%@",[NSThread currentThread]);
    }];


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

代碼示例:

//
//  YYViewController.m
//  03-NSOperation根本3
//
//  Created by 孔醫己 on 14-6-25.
//  Copyright (c) 2014年 itcast. All rights reserved.
//

#import "YYViewController.h"

@interface YYViewController ()

@end


@implementation YYViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    //創立NSInvocationOperation對象,封裝操作
    NSInvocationOperation *operation1=[[NSInvocationOperation alloc]initWithtarget:self selector:@selector(test1) object:nil];
    NSInvocationOperation *operation2=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test2) object:nil];
    //創立對象,封裝操作
    NSBlockOperation *operation3=[NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"NSBlockOperation3--1----%@",[NSThread currentThread]);
    }];
    [operation3 addExecutionBlock:^{
        NSLog(@"NSBlockOperation3--2----%@",[NSThread currentThread]);
    }];
   
    //創立NSOperationQueue
    NSOperationQueue * queue=[[NSOperationQueue alloc]init];
    //把操作添加到隊列中
    [queue addOperation:operation1];
    [queue addOperation:operation2];
    [queue addOperation:operation3];
}


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

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

@end

打印後果:

https://www.ios5.online/ios/UploadFiles_8070/201703/2017031615443845.png (900×83)

留意:體系主動將NSOperationqueue中的NSOperation對象掏出,將其封裝的操作放到一條新的線程中履行。下面的代碼示例中,一共有四個義務,operation1和operation2分離有一個義務,operation3有兩個義務。一共四個義務,開啟了四條線程。經由過程義務履行的時光全體都是273可以看出,這些義務是並行履行的。

提醒:隊列的掏出是有次序的,與打印成果其實不抵觸。這就比如,選手A,BC固然起跑的次序是先A,後B,然後C,然則達到起點的次序卻紛歧定是A,B在前,C在後。
上面應用for輪回打印,可以更顯著的看出義務是並發履行的。

代碼示例:

#import "YYViewController.h"

@interface YYViewController ()

@end


@implementation YYViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    //創立NSInvocationOperation對象,封裝操作
    NSInvocationOperation *operation1=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test1) object:nil];
    NSInvocationOperation *operation2=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test2) object:nil];
    //創立對象,封裝操作
    NSBlockOperation *operation3=[NSBlockOperation blockOperationWithBlock:^{
        for (int i=0; i<5; i++) {
            NSLog(@"NSBlockOperation3--1----%@",[NSThread currentThread]);
        }
    }];
    [operation3 addExecutionBlock:^{
        for (int i=0; i<5; i++) {
        NSLog(@"NSBlockOperation3--2----%@",[NSThread currentThread]);
        }
    }];
   
    //創立NSOperationQueue
    NSOperationQueue * queue=[[NSOperationQueue alloc]init];
    //把操作添加到隊列中
    [queue addOperation:operation1];
    [queue addOperation:operation2];
    [queue addOperation:operation3];
}

-(void)test1
{
    for (int i=0; i<5; i++) {
    NSLog(@"NSInvocationOperation--test1--%@",[NSThread currentThread]);
    }
}

-(void)test2
{
    for (int i=0; i<5; i++) {
    NSLog(@"NSInvocationOperation--test2--%@",[NSThread currentThread]);
    }
}

@end

https://www.ios5.online/ios/UploadFiles_8070/201703/2017031615443839.png (889×273)

3、並發數
(1)並發數:同時執⾏行的義務數.好比,同時開3個線程履行3個義務,並發數就是3
(2)最年夜並發數:統一時光最多只能履行的義務的個數。
(3)最⼤年夜並發數的相干⽅辦法


- (NSInteger)maxConcurrentOperationCount;
- (void)setMaxConcurrentOperationCount:(NSInteger)cnt;


解釋:假如沒有設置最年夜並發數,那末並發的個數是由體系內存和CPU決議的,能夠內存多久開多一點,內存少就開少一點。
留意:num的值其實不代表線程的個數,僅僅代表線程的ID。
提醒:最年夜並發數不要亂寫(5之內),不要開太多,普通以2~3為好,由於固然義務是在子線程停止處置的,然則cpu處置這些過量的子線程能夠會影響UI,讓UI變卡。

4、隊列的撤消,暫停和恢復
 (1)撤消隊列的一切操作

 - (void)cancelAllOperations;

提⽰:也能夠挪用NSOperation的- (void)cancel⽅法撤消單個操作

 (2)暫停和恢復隊列

- (void)setSuspended:(BOOL)b; // YES代表暫停隊列,NO代表恢復隊列

- (BOOL)isSuspended; //以後狀況

(3)暫停和恢復的實用場所:在tableview界面,開線程下載長途的收集界面,對UI會有影響,應用戶體驗變差。那末這類情形,便可以設置在用戶操作UI(如轉動屏幕)的時刻,暫停隊列(不是撤消隊列),停滯轉動的時刻,恢復隊列。

5、操作優先級
 (1)設置NSOperation在queue中的優先級,可以轉變操作的執⾏優先級

- (NSOperationQueuePriority)queuePriority;
- (void)setQueuePriority:(NSOperationQueuePriority)p;

 (2)優先級的取值

NSOperationQueuePriorityVeryLow = -8L,

NSOperationQueuePriorityLow = -4L,

NSOperationQueuePriorityNormal = 0,

NSOperationQueuePriorityHigh = 4,

NSOperationQueuePriorityVeryHigh = 8

解釋:優先級高的義務,挪用的概率會更年夜。

6、操作依附
(1)NSOperation之間可以設置依附來包管履行次序,⽐如必定要讓操作A履行完後,能力履行操作B,可以像上面這麼寫

[operationB addDependency:operationA]; // 操作B依附於操作

(2)可以在分歧queue的NSOperation之間創立依附關系

https://www.ios5.online/ios/UploadFiles_8070/201703/2017031615443837.png (388×187)

留意:不克不及輪回依附(不克不及A依附於B,B又依附於A)。

(3)代碼示例

#import "YYViewController.h"

@interface YYViewController ()

@end


@implementation YYViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    //創立NSInvocationOperation對象,封裝操作
    NSInvocationOperation *operation1=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test1) object:nil];
    NSInvocationOperation *operation2=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test2) object:nil];
    //創立對象,封裝操作
    NSBlockOperation *operation3=[NSBlockOperation blockOperationWithBlock:^{
        for (int i=0; i<5; i++) {
            NSLog(@"NSBlockOperation3--1----%@",[NSThread currentThread]);
        }
    }];
    [operation3 addExecutionBlock:^{
        for (int i=0; i<5; i++) {
        NSLog(@"NSBlockOperation3--2----%@",[NSThread currentThread]);
        }
    }];
   
    //設置操作依附
    //先履行operation2,再履行operation1,最初履行operation3
    [operation3 addDependency:operation1];
    [operation1 addDependency:operation2];
   
    //不克不及是互相依附
//    [operation3 addDependency:operation1];
//    [operation1 addDependency:operation3];
   
    //創立NSOperationQueue
    NSOperationQueue * queue=[[NSOperationQueue alloc]init];
    //把操作添加到隊列中
    [queue addOperation:operation1];
    [queue addOperation:operation2];
    [queue addOperation:operation3];
}


-(void)test1
{
    for (int i=0; i<5; i++) {
    NSLog(@"NSInvocationOperation--test1--%@",[NSThread currentThread]);
    }
}

-(void)test2
{
    for (int i=0; i<5; i++) {
    NSLog(@"NSInvocationOperation--test2--%@",[NSThread currentThread]);
    }
}

@end

打印檢查:

https://www.ios5.online/ios/UploadFiles_8070/201703/2017031615443868.png (907×305)

A做完再做B,B做完才做C。
留意:必定要在添加上前,停止設置。
提醒:義務添加的次序其實不可以或許決議履行次序,履行的次序取決於依附。應用Operation的目標就是為了閃開發人員不再關懷線程。
 
 
5.操作的監聽
可以監聽一個操作的履行終了

- (void (^)(void))completionBlock;
- (void)setCompletionBlock:(void (^)(void))block;

代碼示例

第一種方法:可以直接跟在義務前面編寫須要完成的操作,如這裡鄙人載圖片後,緊隨著下載第二張圖片。然則這類寫法有的時刻把兩個不相干的操作寫到了一個代碼塊中,代碼的可浏覽性不強。

#import "YYViewController.h"

@interface YYViewController ()

@end

@implementation YYViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    //創立對象,封裝操作
    NSBlockOperation *operation=[NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"-operation-下載圖片-%@",[NSThread currentThread]);
        //.....下載圖片後持續停止的操作
        NSLog(@"--接著下載第二張圖片--");
    }];
    
    //創立隊列
    NSOperationQueue *queue=[[NSOperationQueue alloc]init];
    //把義務添加到隊列中(主動履行,主動開線程)
    [queue addOperation:operation];
}

@end

第二種方法:

#import "YYViewController.h"

@interface YYViewController ()

@end

@implementation YYViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    //創立對象,封裝操作
    NSBlockOperation *operation=[NSBlockOperation blockOperationWithBlock:^{
        for (int i=0; i<10; i++) {
            NSLog(@"-operation-下載圖片-%@",[NSThread currentThread]);
        }
    }];
   
    //監聽操作的履行終了
    operation.completionBlock=^{
        //.....下載圖片後持續停止的操作
        NSLog(@"--接著下載第二張圖片--");
    };
   
    //創立隊列
    NSOperationQueue *queue=[[NSOperationQueue alloc]init];
    //把義務添加到隊列中(主動履行,主動開線程)
    [queue addOperation:operation];
}

@end

打印檢查:

https://www.ios5.online/ios/UploadFiles_8070/201703/2017031615443874.png (880×155)

解釋:在上一個義務履行完後,會履行operation.completionBlock=^{}代碼段,且是在以後線程履行(2)。

【iOS多線程運用開辟中應用NSOperation類的根本辦法】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!

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