多线程编程方式——NSOperation

2016-03-24  本文已影响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];

}

上一篇下一篇

猜你喜欢

热点阅读