美文网首页
多线程编程方式——NSOperation

多线程编程方式——NSOperation

作者: 不要打听我的故事丶 | 来源:发表于2016-03-24 20:10 被阅读25次

    前言:

    多线程编程是防止主线程堵塞,增加运行效率等等的最佳方法,而原始的多线程方法编程方法有很多毛病,包括线程锁死等。在Cocoa中,Apple提供了NSOperation这个类,提供了一个优秀的多线程编写方法。

    首先是建立NSOperationQueue和NSOperation、NSOperationQueue会建立一个线程管理器。每一个加入到线程的NSOperation会有序的执行。

    一、什么是NSOperation?

    NSOperation是除NSThread之外的第二种多线程编程方式。

    采用NSOperation(线程操作,通常用他的子类)和NSOperationQueue(线程队列)搭配来做多线程的开发。采用NSOperation指定一个操作。把这个操作放到线程队列(线程池)中。让线程队列来安排它的生命周期。

    二、NSOperation与NSThread有什么区别?

     ①、NSThread需要启动,也就是说需要费心管理线程的生命周期,而采用NSOperation只需要将线程放到线程队列中即可、线程队列负责管理、执行所有的线程操作。

    ②、管理线程的最大并发数,也就是同时执行任务数。

    ③、控制线程之间的依赖关系,NSOperation之间可以设置依赖以保证顺序执行,比如一定要让操作1执行完后,才能执行操作2,线程之间不能相互依赖。比如A依赖B、B又依赖A。

    ④、队列的取消、暂停、恢复

    下面代码实际展示NSOperation的应用

    使用NSOperationQueue的过程:

    1)建立一个NSOperationQueue的对象

    2)建立一个NSOperation(一般都是用它的子类)对象

    3)将NSOperation对象加入到NSOperationQueue中

    NSOperation开发总共有三种方式

       1、NSInvocationIOperation和NSOperationQueue搭配进行多线程开发

      2、NSBlockOperation和NSOperationQueue搭配开发多线程

    3、用自定义与NSOperation的类与NSOperation搭配

    #pragma mark****此处练习是利用多线程加载网络图片******

    步骤:

    1.创建视图

    2.创建线程队列

    3.创建线程

    4.将线程放到线程队列中

    5.在子线程加载网络资源

    6.回到主线程

    7.更新UI

    *********************************************

    //

    //  ViewController.m

    //  NSOperation的复习

    //

    //  Created by scsys on 16/3/3.

    //  Copyright © 2016年 pls. All rights reserved.

    //

    #import "ViewController.h"

    //宏定义一个网络资源文件的路径

    #define kurl @"http://store.storeimages.cdn-apple.com/8748/as-images.apple.com/is/image/AppleInc/aos/published/images/s/38/s38ga/rdgd/s38ga-rdgd-sel-201601?wid=848&hei=848&fmt=jpeg&qlt=80&op_sharpen=0&resMode=bicub&op_usm=0.5,0.5,0,0&iccEmbed=0&layer=comp&.v=1454777389943"

    @interface ViewController ()

    {

    UIImageView *imageView;

    }

    @end

    @implementation ViewController

    - (void)viewDidLoad {

    [super viewDidLoad];

    //利用多线程加载一张网络图片

    // 步骤:

    /*

    1、创建一个视图

    2、创建一个线程队列

    3、创建一个线程

    4、将线程添加到线程队列中

    5、在子线程中加载网络资源

    6、回到主线程

    7、更新UI

    */

    //1.创建一个视图、此处一般将视图设为全局变量

    imageView = [[UIImageView alloc]initWithFrame:CGRectMake(50, 200, 200, 200)];

    //  让加载的网络图片根据imageView的大小自适应

    imageView.contentMode = UIViewContentModeScaleAspectFit;

    [self.view addSubview:imageView];

    //2、创建一个线程队列

    // 在此处直接用了一个new,相当于直接给它alloc、init了。不用写的那么复杂

    NSOperationQueue *operationQueue = [NSOperationQueue new];

    //3、创建一个线程,此处用NSOperation的子类(NSInvocationOperation)

    // 创建一个NSInvocationOperation对象,并初始化到方法。

    // 在这里selcetor参数后面的值是你想在另外一个线程中运行的方法(函数,Method)

    // 在这里object后的值是想传递给前面方法的数据

    NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(loadResource) object:nil];

    //4、将线程添加到线程队列中

    // 下面将我们建立的操作“operation”加入到本地程序的共享队列中,(加入后方法就会立刻被执行)

    [operationQueue addOperation:invocationOperation];

    }

    //5、在子线程中加载网络资源

    -(void)loadResource{

    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:kurl        ]];

    UIImage *image = [UIImage imageWithData:data];

    //6、回到主线程

    [[NSOperationQueue mainQueue]addOperationWithBlock:^{

    //7、更新UI

    imageView.image = image;

    }];

    }

    - (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

    }

    @end

    #pragma mark ----NSOperation的第二种开发方式-------NSBlockOperation

    #pragma mark=====NSOperation的第二种开发方式==========

    -(void)viewDidLoad{

    [super viewDidLoad];

    self.view.backgroundColor = [UIColor whiteColor];

    self.edgesForExtendedLayout =  UIRectEdgeNone ;

    //1、创建一个视图

    imageView = [[UIImageView alloc]initWithFrame:CGRectMake(50, 50, 200, 200)];

    imageView.contentMode = UIViewContentModeScaleAspectFit;

    [self.view addSubview:imageView];

    //2、创建一个县城队列

    NSOperationQueue *operationQueue = [NSOperationQueue new];

    //3、创建一个线程

    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{

    //5、加载网络资源文件

    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:kurl]];

    UIImage *image = [UIImage imageWithData:data];

    //6、回到主线程

    [[NSOperationQueue mainQueue]addOperationWithBlock:^{

    // 7、更新UI

    imageView.image = image;

    }];

    }];

    //4、将线程放到线程队列中

    [operationQueue addOperation:blockOperation];

    }

    相关文章

      网友评论

          本文标题:多线程编程方式——NSOperation

          本文链接:https://www.haomeiwen.com/subject/czqokttx.html