zoukankan      html  css  js  c++  java
  • iOS多线程编程之NSOperation的基本操作

    一、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,实现内部相应的⽅法

    二、 具体说明

    1.NSInvocationOperation子类

    创建对象和执行操作:

    //创建操作对象,封装要执行的任务
    //NSInvocationOperation   封装操作
      NSInvocationOperation *operation=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test) object:nil];
    //执行操作
      [operation start];

    说明:一旦执⾏操作,就会调用target的test方法

    代码示例:

    //  YYViewController.m
    //  01-NSOperation基本1
     #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 

    打印查看:

    注意:操作对象默认在主线程中执行,只有添加到队列中才会开启新的线程。即默认情况下,如果操作没有放到队列中queue中,都是同步执行。只有将NSOperation放到一个NSOperationQueue中,才会异步执行操作 

    2.NSBlockOperation子类

    创建对象和添加操作:

    //创建NSBlockOperation操作对象
      NSBlockOperation *operation=[NSBlockOperation blockOperationWithBlock:^{
    //......
      }];
    //添加操作
     [operation addExecutionBlock:^{
           //....
     }];

    代码示例:

    代码1:

      YYViewController.m
      #import "YYViewController.h" 
      @interface YYViewController () 
      @end 
      @implementation YYViewController 
     - (void)viewDidLoad {
        [super viewDidLoad];    
       //创建NSBlockOperation操作对象
         NSBlockOperation *operation=[NSBlockOperation blockOperationWithBlock:^{
           NSLog(@"NSBlockOperation------%@",[NSThread currentThread]);
         }];     
       //开启执行操作
       [operation start];
       }
     @end

    打印查看:

    代码2:

      YYViewController.m
      #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

    注意:只要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
       #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

    打印效果:

    注意:系统自动将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

  • 相关阅读:
    494 Target Sum 目标和
    493 Reverse Pairs 翻转对
    492 Construct the Rectangle 构建矩形
    491 Increasing Subsequences 递增子序列
    488 Zuma Game 祖玛游戏
    486 Predict the Winner 预测赢家
    485 Max Consecutive Ones 最大连续1的个数
    483 Smallest Good Base
    Django Form组件
    Django Auth组件
  • 原文地址:https://www.cnblogs.com/lxlx1798/p/6642963.html
Copyright © 2011-2022 走看看