zoukankan      html  css  js  c++  java
  • NSOperation简介

    1.NSOperation的作用

    配合使用NSOperation和NSOperationQueue也能实现多线程编程。

    2.NSOperation和NSOperationQueue实现多线程的具体步骤:

    1)先将需要执行的操作封装到一个NSOperation对象中。

    2)然后将NSOperation对象添加到NSOperationQueue中。

    3)系统会自动将NSOperationQueue中的NSOperation取出来。

    4)将取出来的NSOperation封装的操作放到一条新线程中执行。

    3.NSOperation的子类

    NSOperation是个抽象类,并不具备封装操作的能力,必须使用它的子类。

    使用NSOperation子类的方式有3种:

    1) NSInvocationOperation

    2) NSBlockOperation

    3) 自定义子类继承NSOperation,实现内部相应的方法。

    4.基本使用代码示例

    /* NSInvocationOperation使用*/

    -(void)downloadImage:(id)obj

    {

           NSLog(@”%@”, obj);

    }

    //创建操作

    NSOperation*op = [[NSInvocationOperation  alloc]initWithTarget:self selector:@selector(downloadImage:) object:@”Invocation”];

    //启动,直接在当前线程执行

    [opstart];

    /*放到队列(GCD里面的并发队列(全局)队列使用最多。所以,NSOperationQueue技术直接把GCD里面的并发队列封装起来)。

    NSOperationQueue队列,本质就是GCD里面的并发队列。*/

    NSOperationQueue*queue = [[NSOperationQueue alloc] init];

    //只要把操作添加到队列,会自动异步执行调度方法

    [queueaddOperation:op];

    /*NSBlockOperation 使用*/

    //相当于GCD的并发队列

    NSOperationQueue*queue = [[NSOperationQueue alloc]init];

    for(int I= 0; I < 10; I ++){

           //异步执行

           NSBlockOperation *op = [NSBlockOperationblockOperationWithBlock:^{

                  NSLog(@”%@”, [NSThreadcurrentThread]);

    }];

    //把block操作放到队列中

    [queue addOperation:op];

    }

    /*线程间通信*/

    NSOperationQueue*queue = [[NSOperationQueue alloc]init];

    [queueaddOperationWithBlock:^{

           NSLog(@”耗时的操作 %@”,[NSThread currentThread]);

           //在主线程更新UI

           [[NSOperationQueue mainQueue]addOperationWithBlock:^{

           //更新UI的操作

           }];

    }];

    小结:

    1) 只要是NSOperation的子类,就能添加到操作队列。

    2) 一旦操作添加到队列,就会自动异步执行。

    3) 如果没有添加到队列,而是使用start方法,会在当前线程执行操作。

    4) 如果要做线程间通信,可以使用[NSOperationQueue mainQueue]拿到主队列,往主队列添加操作(更新UI)。

    5.最大并发数

    1)什么是并发数

    同时执行的任务数。

    比如,同时开3个线程执行3个任务,并发数就是3.

    2)最大并发数的相关方法

    -(NSInteger)maxConcurrentOperationCount;

    -(void)setMaxConcurrentOperationCount:(NSInteger)cnt;

    6.挂起

    暂停/继续功能。

    7.高级操作代码示例

    /*并发数*/

    /*一个程序中,负责所有的调度,全局的*/

    NSOperationQueue*queue = [[NSOperationQueue alloc]init];

    -(void)opDemo{

    /*设置最大的并发数,是同时执行任务的数量,不是线程的数量。

    任务刚执行完的时候,线程有一个回收到线程池,再拿出来使用的过程。所以这个时候,还有其他线程的话,则会直接拿来使用。*/

    queue. maxConcurrentOperationCount = 2;

    for(int I = 0; I < 10; I ++){

                  NSOperation*op = [NSBlockOperation blockOperationWithBlock:^{

                         NSLog(@”%@”,[NSThread currentThread]);

                  }];

                  [queueaddOperation:op];

    }

    }

    /*挂起:暂停/继续*/

    /*只是对队列的操作,不会影响已经在执行的操作。*/

    queue.suspended= YES;

    /*取消:取消队列里所有的操作*/

    /*取消队列里的所有操作

    取消操作,并不会影响队列的挂起状态。*/

    [queuecancelAllOperation];

    /*依赖关系*/

    -(void)dependency

    {

    /*

    例子:

    1.      下载一个小说的压缩包。

    2.      解压缩,删除压缩包。

    3.      更新UI。

    */

           NSBlockOperation *op 1 =[NSBlockOperation blockOperationWithBlock:^{

                  NSLog(@” 下载一个小说的压缩包”);

           }];

           NSBlockOperation *op 2 =[NSBlockOperation blockOperationWithBlock:^{

                  NSLog(@” 解压缩,删除压缩包”);

           }];

           NSBlockOperation *op3  = [NSBlockOperation  blockOperationWithBlock:^{

                  NSLog(@” 更新UI”);

           }];

           /*指定任务之间的依赖关系,依赖关系可以跨队列。(可以在子线程执行耗时操作,在主线程更新UI)*/

           [op2 addDependency:op1];

    [op3 addDependency:op2];

    /*注意点:一定不要出现循环依赖关系。*/

           // waitUntilFinished类似于GCD的调度组通知。NO,不等待,会直接执行后面的代码

           [queue addOperation:@[op1, op2, op3]waitUntilFinished:YES];

           //在主线程更新UI

           [[NSOperationQueue mainQueue] addOperation:op3];

           NSLog(@”yeah”);

    }

    8.GCD与NSOperation对比

    GCD(iOS4.0推出):

    将任务(block)添加到队列(串行/并发(全局)),指定执行任务的方法(同步(阻塞)/异步)。

    拿到dispatch_get_main_queue(),线程间通信。

    NSOperation无法做到一次性执行,延迟执行,调度组(NSOperation相对复杂)。

    NSOperation(iOS2.0推出):

    将操作(异步执行)添加到队列(并发/全局)中。

    [NSOperationQueuemainQueue]拿到主队列,任务添加到主队列,就会在主线程执行。线程间通信。

    GCD不好实现“最大并发数”。

    挂起。

    取消所有任务。

    依赖关系。

    9.内存警告

    /*在真实开发中,一定要注意这个方法*/

    -(void)didReceiveMemoryWaring

    {

           [super didReceiveMemoryWaring];

           /*需要在这里做一些内存清理工作,如果不处理,会被系统强制闪退。*/

           //清理缓存

           //取消下载队列里面的任务

    }

    10.几种空

    [NSNullnull]:空对象,可以放到字典或数组里。

    NULL:C语言的空指针。

    nil:OC指向空对象的指针。

    Nil:空类。

    11.block会有循环引用的风险(对外部的变量强引用)

    self使用要注意。(block中,self可以这样使用:__weak typedef(self) weakSelf = self;)

    借助dealloc方法,判断是否循环引用。

    12.自定义NSOperation

    步骤:

    1)创建继承NSOperation的类。

    2)在新创建的类里重写-(void)main方法,在里面实现想要执行的任务。

    重写-(void)main方法注意点:

    1>    自己创建自动释放池(因为如果是异步操作,无法访问主线程的自动释放池)。

    2>    经常通过-(BOOL)isCancelled方法检测操作是否被取消,对取消做出响应。

  • 相关阅读:
    如何规范自己的编程以及软件开发目录(二)
    关于README的内容
    关于编程编程规范以及开发目录的规范性
    第五章:条件、循环以及其他语句(上)
    第四章 当索引行不通时
    python-zipfile模块
    python-shutil模块
    python-sys模块
    python-os模块
    python-threading.Thread(多线程)
  • 原文地址:https://www.cnblogs.com/chars/p/4936075.html
Copyright © 2011-2022 走看看