NSoperation 和 NSOperationQueue
- NSOperation 是個(gè)抽象類,并不具備封裝操作的能力,必須使用他的子類
- 使用NSOperation子類的方式有3種
- NSInvocationOperation
- NSBlockOperation
- 自定義子類繼承NSOperation,實(shí)現(xiàn)內(nèi)部相應(yīng)的方法
基本使用NSOperation
- NSOperationQueue的隊(duì)列類型
- 主隊(duì)列:
- 初始化方法:[NSOperationQueue mainQueue]
- 凡是添加到主隊(duì)列中的任務(wù)(NSOperation),都會(huì)放到主隊(duì)列中執(zhí)行
- 其他隊(duì)列:
- 初始化方法:[[NSOperationQueue alloc] init]
- 同時(shí)包含了:串行、并發(fā)功能
- 添加這種隊(duì)列的任務(wù)(NSOperation),就會(huì)自動(dòng)放到子線程執(zhí)行
最大并發(fā)操作數(shù)(MaxConcurrentOperationCount)
屬性(suspend)掛起 (Cancel)取消操作
線程的使用
#第一種類型寫法
// 創(chuàng)建隊(duì)列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 創(chuàng)建操作(任務(wù))
// 創(chuàng)建NSInvocationOperation
NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download1) object:nil];
NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download2) object:nil];
// 創(chuàng)建NSBlockOperation
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"download3 --- %@", [NSThread currentThread]);
}];
[op3 addExecutionBlock:^{
NSLog(@"download4 --- %@", [NSThread currentThread]);
}];
[op3 addExecutionBlock:^{
NSLog(@"download5 --- %@", [NSThread currentThread]);
}];
NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"download6 --- %@", [NSThread currentThread]);
}];
// 創(chuàng)建HBOperation(自定義)
HBOperation *op5 = [[XMGOperation alloc] init];
// 添加任務(wù)到隊(duì)列中
[queue addOperation:op1];
// [op1 start] 默認(rèn)已經(jīng)執(zhí)行了
[queue addOperation:op2];
// [op2 start]
[queue addOperation:op3];
// [op3 start]
[queue addOperation:op4];
// [op4 start]
[queue addOperation:op5];
// [op5 start]
總結(jié): 先創(chuàng)建隊(duì)列,然后創(chuàng)建操作,在將操作添加到隊(duì)列中執(zhí)行
#第二種類型寫法
// 創(chuàng)建隊(duì)列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
NSLog(@"download1 --- %@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
NSLog(@"download2 --- %@", [NSThread currentThread]);
}];
總結(jié): 讓Queue使用block進(jìn)行添加操作(Operation )
# 最大并發(fā)數(shù)
// 創(chuàng)建隊(duì)列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 設(shè)置最大并發(fā)操作數(shù)
// queue.maxConcurrentOperationCount = 2;
queue.maxConcurrentOperationCount = 1; // 就變成了串行隊(duì)列
// 添加操作
[queue addOperationWithBlock:^{
NSLog(@"download1 --- %@", [NSThread currentThread]);
[NSThread sleepForTimeInterval:0.01];
}];
[queue addOperationWithBlock:^{
NSLog(@"download2 --- %@", [NSThread currentThread]);
[NSThread sleepForTimeInterval:0.01];
}];
[queue addOperationWithBlock:^{
NSLog(@"download3 --- %@", [NSThread currentThread]);
[NSThread sleepForTimeInterval:0.01];
}];
[queue addOperationWithBlock:^{
NSLog(@"download4 --- %@", [NSThread currentThread]);
[NSThread sleepForTimeInterval:0.01];
}];
[queue addOperationWithBlock:^{
NSLog(@"download5 --- %@", [NSThread currentThread]);
[NSThread sleepForTimeInterval:0.01];
}];
[queue addOperationWithBlock:^{
NSLog(@"download6 --- %@", [NSThread currentThread]);
[NSThread sleepForTimeInterval:0.01];
}];
總結(jié):最大并發(fā)數(shù)(maxConcurrentOperationCount)默認(rèn)是-1,是否開(kāi)啟多線程取決于最大并發(fā)數(shù)
**************************************************************************
#掛起(suspend)
@interface ViewController ()
/** 隊(duì)列 */
@property (nonatomic, strong) NSOperationQueue *queue;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 創(chuàng)建隊(duì)列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 設(shè)置最大并發(fā)操作數(shù)
queue.maxConcurrentOperationCount = 1; // 就變成了串行隊(duì)列
// 添加操作
[queue addOperationWithBlock:^{
for (NSInteger i = 0; i<5000; i++) {
NSLog(@"download1 -%zd-- %@", i, [NSThread currentThread]);
}
}];
[queue addOperationWithBlock:^{
for (NSInteger i = 0; i<1000; i++) {
NSLog(@"download2 --- %@", [NSThread currentThread]);
}
}];
[queue addOperationWithBlock:^{
for (NSInteger i = 0; i<1000; i++) {
NSLog(@"download3 --- %@", [NSThread currentThread]);
}
}];
self.queue = queue;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (self.queue.isSuspended) {
// 恢復(fù)隊(duì)列,繼續(xù)執(zhí)行
self.queue.suspended = NO;
} else {
// 暫停(掛起)隊(duì)列,暫停執(zhí)行
self.queue.suspended = YES;
}
}
總結(jié):當(dāng)線程掛起的時(shí)候,當(dāng)前線程會(huì)被停止,后面的線程不會(huì)再繼續(xù)執(zhí)行了,如果是當(dāng)前for循環(huán)并沒(méi)有結(jié)束,那么即使是掛起狀態(tài)當(dāng)前for循環(huán)也會(huì)執(zhí)行完成,因?yàn)椋琭or循環(huán)是不可控的。
**************************************************************************
#取消(cancelAllOperations)
[self.queue cancelAllOperations];
總結(jié):取消隊(duì)列中的所有線程
#自定義NSOperation
1. 首先得繼承NSOperation(.h文件)
2.重寫main方法(.m文件)
***********************.m文件**************************
/**
* 需要執(zhí)行的任務(wù)
*/
- (void)main
{
for (NSInteger i = 0; i<1000; i++) {
NSLog(@"download1 -%zd-- %@", i, [NSThread currentThread]);
}
if (self.isCancelled) return;
for (NSInteger i = 0; i<1000; i++) {
NSLog(@"download2 -%zd-- %@", i, [NSThread currentThread]);
}
if (self.isCancelled) return;
for (NSInteger i = 0; i<1000; i++) {
NSLog(@"download3 -%zd-- %@", i, [NSThread currentThread]);
}
if (self.isCancelled) return;
}
注意:自定義的Operation需要判斷是否取消了
**********************************************************
# 操作依賴
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"download1----%@", [NSThread currentThread]);
}];
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"download2----%@", [NSThread currentThread]);
}];
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"download3----%@", [NSThread currentThread]);
}];
NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
for (NSInteger i = 0; i<10; i++) {
NSLog(@"download4----%@", [NSThread currentThread]);
}
}];
NSBlockOperation *op5 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"download5----%@", [NSThread currentThread]);
}];
op5.completionBlock = ^{
NSLog(@"op5執(zhí)行完畢---%@", [NSThread currentThread]);
};
// 設(shè)置依賴
[op3 addDependency:op1];
[op3 addDependency:op2];
[op3 addDependency:op4];
[queue addOperation:op1];
[queue addOperation:op2];
[queue addOperation:op3];
[queue addOperation:op4];
[queue addOperation:op5];
}
總結(jié):所謂依賴(Dependency)就是當(dāng)前對(duì)象想要執(zhí)行就必須讓他的依賴先完成
所以op3想要先執(zhí)行就必須讓op1 op2 op4 先執(zhí)行,也就是op3 在op1 op2 op4 執(zhí)行后面
**************************************************************************
#實(shí)現(xiàn)進(jìn)程的通信
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
__block UIImage *image1 = nil;
// 下載圖片1
NSBlockOperation *download1 = [NSBlockOperation blockOperationWithBlock:^{
// 圖片的網(wǎng)絡(luò)路徑
NSURL *url = [NSURL URLWithString:@"http://img.pconline.com.cn/images/photoblog/9/9/8/1/9981681/200910/11/1255259355826.jpg"];
// 加載圖片
NSData *data = [NSData dataWithContentsOfURL:url];
// 生成圖片
image1 = [UIImage imageWithData:data];
}];
__block UIImage *image2 = nil;
// 下載圖片2
NSBlockOperation *download2 = [NSBlockOperation blockOperationWithBlock:^{
// 圖片的網(wǎng)絡(luò)路徑
NSURL *url = [NSURL URLWithString:@"http://pic38.nipic.com/20140228/5571398_215900721128_2.jpg"];
// 加載圖片
NSData *data = [NSData dataWithContentsOfURL:url];
// 生成圖片
image2 = [UIImage imageWithData:data];
}];
// 合成圖片
NSBlockOperation *combine = [NSBlockOperation blockOperationWithBlock:^{
// 開(kāi)啟新的圖形上下文
UIGraphicsBeginImageContext(CGSizeMake(100, 100));
// 繪制圖片
[image1 drawInRect:CGRectMake(0, 0, 50, 100)];
image1 = nil;
[image2 drawInRect:CGRectMake(50, 0, 50, 100)];
image2 = nil;
// 取得上下文中的圖片
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
// 結(jié)束上下文
UIGraphicsEndImageContext();
// 回到主線程
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.imageView.image = image;
}];
}];
[combine addDependency:download1];
[combine addDependency:download2];
[queue addOperation:download1];
[queue addOperation:download2];
[queue addOperation:combine];
}
總結(jié):合成圖片必須有兩章圖片,所以得用依賴來(lái)設(shè)置順序,下載圖片,合成圖片都是放在子線程中的刷新UI是返回主線程中的。
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。