NSOperation(操作)简介

本文详细介绍了NSOperation及NSOperationQueue的概念与使用方法,包括它们与GCD的区别、如何创建与使用NSInvocationOperation和NSBlockOperation、操作依赖设置、最大并发数设定以及队列的取消与暂停技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



NSOperation 使用 1. 简介  
重点 : 理解操作 NSOperation 和操作队列 NSOperationQueue!
{
   
1. NSOperation( 操作 ) 简介 :
   
    NSOperation:
// 本质是对 GCD 的封装 , OC 语言 .
   
    NSOperation
GCD 的比较 :
   
    GCD
使用场合 :
   
一些简单的需求 , 简单的多线程操作 . // 简单高效
   
    NSOperation
使用场合 :
   
各个操作之间有依赖关系 , 操作需要取消 / 暂停 ; 需要限制同时执行的线程数量 , 让线程在某时刻停止 / 继续等 .
   
   
配合使用 NSOperation NSOperationQueue 也可以实现多线程 .
   
   
总结:
   
" 开启 " 线程的角度考虑 : 使用 GCD;
   
   
" 管理 " 线程的角度考虑 : 使用 NSOperation;

   
2. NSOperation 使用 :
   
    NSOperation:
抽象类 , 不能直接使用 , 需要使用其子类 .
   
   
抽象类 : 定义子类共有的属性和方法 . // CAAnimation/CAPropertyAnimation...
   
   
两个常用子类 : NSInvocationOperation( 调用 ) NSBlockOperation( );
   
               
两者没有本质区别 , 后者使用 Block 的形式组织代码 , 使用相对方便 .
   
   
自定义子类继承自 NSOperation, 实现内部相应的方法 . // 高级用法
}
/*----------------------------  NSOperation 使用 2.NSOperation ------------------------------*/
重点 : 1. NSBlockOperation, NSInvocationOperation 的简单使用 .
{
   
1. 创建 NSInvocationOperation 对象
   
   
// 创建 NSInvocationOperation
    NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:
self selector: @selector (longTimeOperation:) object: @"op1" ];
   
   
// 默认情况下 , 调用 start 方法之后 , 不会开启新线程 , 只会在当前线程执行操作 .
    [op1 start];
   
   
注意 : 只有将 NSOperation 放到一个 NSOperationQueue , 才会异步执行操作 .
   
   
2. 创建 NSBlockOperation 对象
   
   
// 创建 NSBlockOperation
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(
@" 下载图片 1---%@" ,[NSThread currentThread]);
    }];
   
// 添加更多操作
    [op2 addExecutionBlock:^{
        NSLog(
@" 下载图片 2---%@" ,[NSThread currentThread]);
    }];
    [op2 addExecutionBlock:^{
        NSLog(
@" 下载图片 3---%@" ,[NSThread currentThread]);
    }];
   
   
// 只要 NSBlockOperation 中封装的操作数 > 1, 调用 start 方法之后就会开启多条线程并发执行
   
// 如果 NSBlockOperation 中封装的操作数 == 1, 调用 start 方法之后 , 不会开启新线程 , 只会在当前线程执行操作
    [op2 start];
   
   
注意 : 只要 NSBlockOperation 中封装的操作数 > 1 , 就会异步执行这些操作 .( 将操作添加到 NSOperationQueue 中或者直接调用 start 方法都会开启多条线程异步执行 ).
}
/*---------------------------- NSOperation 使用 3.NSOperationQueue --------------------------*/
重点 : 将操作添加到队列中 ;
{
    NSOperation
可以调用 start 方法来执行任务 , 但默认是同步执行的 .
   
NSOperation 添加到 NSOperationQueue( 操作队列 ) , 系统会自动异步执行 NSOperationQueue 中的操作 .
   
   
1. NSOperationQueue( 操作队列 ):
   
   
主队列 : 主队列中的操作都自动在主线程执行 !
   
   
非主队列 : 非主队列中的操作都自动在子线程执行 !
   
    <
1 > 主队列
    [NSOperationQueue mainQueue]
// 获取主队列
   
添加到 " 主队列 " 中的操作 , 都会放在主线程执行 !
   
    <
2 > 非主队列
    [[NSOperationQueue alloc] init];
// 创建非主队列
   
添加到 " 非主队列 " 中得操作 , 都会放在子线程中执行 .
   
   
2. 使用 : 添加操作到操作队列中 .
   
   
// 创建 NSInvocationOperation 操作
    NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:
self selector: @selector (longTimeOperation:) object: @"op1" ];
   
   
// 创建 NSBlockOperation 操作
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(
@" 下载图片 1---%@" ,[NSThread currentThread]);
    }];

   
// 1. 创建一个 NSOperationQueue
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
   
   
// 2. 将操作添加到队列中 .
    [queue addOperation:op1];
    [queue addOperation:op2];
   
   
注意 : 另外一种添加操作到队列中的方法 : block
    [queue addOperationWithBlock:^{
        NSLog(
@" 下载图片 5---%@" ,[NSThread currentThread]);
    }];
   
   
推荐使用 : block // 简单 . 自己哪个使用熟练就用哪个 .
   
   
注意 : 队列中任务的执行是无序的 .
   
}
/*-------------------------------- NSOperation 使用 4. 常见用法 1 -------------------------------*/
重点 : 1. 设置操作依赖 . 2. 设置最大并发数 .
{
   
问题 : 是否可以让队列中的操作有序执行 ?
   
   
回答上问题 : , 设置操作依赖 .
   
   
1. NSOperation 设置操作依赖 : // 执行顺序 : op1,op2,op3;
   
   
// 操作 op3 依赖于操作 op2;
    [op3 addDependency:op2];
   
// 操作 op2 依赖于操作 op1;
    [op2 addDependency:op1];
   
   
注意 : 不能相互依赖 .
   
   
2. NSOperationQueue 设置最大并发数 .
   
   
并发数 : 同时开启的线程数 .
   
   
// 创建操作队列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
   
// 设置操作队列的最大并发数
    queue.maxConcurrentOperationCount =
3 ;
    [queue setMaxConcurrentOperationCount:
3 ];
}
/*-------------------------------- NSOperation 使用 5. 常见用法 2 -------------------------------*/
重点 : 1. 队列的取消 / 暂停 / 恢复   2. 线程间通信 . 注意问题 : 为毛要取消 / 恢复队列 ? 在什么时候用 ?
{
   
1. NSOperationQueue 的取消 / 暂停 / 恢复
   
   
// 取消操作 op1. 取消单个操作 .
    [op1 cancel];
   
// 取消所有操作 , 不会再次恢复
    [queue cancelAllOperations];
   
// 暂停所有操作 ; 注意 , 已经开始的操作不会暂停 .
    [queue setSuspended:
YES ];
   
// 重新开始所有操作
    [queue setSuspended:
NO ];
   
   
: 为毛要取消恢复队列 ? 在什么时候用 ?
   
   
: 1. 为了内存管理 , 处理内存警告 ; 2. 为了用户体验 , 保证滚动流畅 .
   
   
// 接收到内存警告的时候果断取消队列中的所有操作
    - (
void )didReceiveMemoryWarning
    {
        [
super didReceiveMemoryWarning];
       
        [queue cancelAllOperations];
// 取消队列中的所有任务(不可恢复)
    }
   
// 开始滚动的时候暂停队列中的任务 .
    - (
void )scrollViewWillBeginDragging:(UIScrollView *)scrollView
    {
        [queue setSuspended:
YES ]; // 暂停队列中的所有任务
    }
   
// 滚动结束的时候恢复队列中的任务 .
    - (
void )scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:( BOOL )decelerate
    {
        [queue setSuspended:
NO ]; // 恢复队列中的所有任务
    }

   
2. 线程间通信   // 子线程下载图片 , 主线程设置图片 .
   
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
   
    [queue addOperationWithBlock:^{
       
// 1. 异步下载图片
        NSURL *url = [NSURL URLWithString:
@"http://d.hiphotos.baidu.com/image/pic/item/37d3d539b6003af3290eaf5d362ac65c1038b652.jpg" ];
        NSData *data = [NSData dataWithContentsOfURL:url];
        UIImage *image = [UIImage imageWithData:data];
       
       
// 2. 回到主线程,显示图片
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
           
self .imageView.image = image;
        }];
    }];
   
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值