1.默认情况下,NSOperation并不具备封装操作的能力,必须使用它的子类,使用NSOperation子类的方式有3种:

1> NSInvocationOperation

2> NSBlockOperation

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

这讲先介绍如何用NSOperation封装一个操作,后面再结合NSOperationQueue来使用。

## 一、NSInvocationOperation

NSInvocationOperation *operation = [[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run:) object:@"mj"] autorelease]; 2 [operation start];

* 第1行初始化了一个NSInvocationOperation对象,它是基于一个对象和selector来创建操作

* 第2行调用了start方法,紧接着会马上执行封装好的操作,也就是会调用self的run:方法,并且将@"mj"作为方法参数

* 这里要注意:默认情况下,调用了start方法后并不会开一条新线程去执行操作,而是在当前线程同步执行操作。只有将operation放到一个NSOperationQueue中,才会异步执行操作。

## 二、NSBlockOperation

### 1.同步执行一个操作

NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^(){ 2        NSLog(@"执行了一个新的操作");

3 }];

4  // 开始执行任务

5 [operation start];

* 第1行初始化了一个NSBlockOperation对象,它是用一个Block来封装需要执行的操作

* 第2行调用了start方法,紧接着会马上执行Block中的内容

* 这里还是在当前线程同步执行操作,并没有异步执行

### 2.并发执行多个操作

NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^(){

2   NSLog(@"执行第1次操作,线程:%@", [NSThread currentThread]);

3 }];

4

5 [operation addExecutionBlock:^() {

6   NSLog(@"又执行了1个新的操作,线程:%@", [NSThread currentThread]);

7 }];

8

9 [operation addExecutionBlock:^() {

10   NSLog(@"又执行了1个新的操作,线程:%@", [NSThread currentThread]);

11 }];

12

13 [operation addExecutionBlock:^() {

14   NSLog(@"又执行了1个新的操作,线程:%@", [NSThread currentThread]);

15 }];

16

17 // 开始执行任务

18 [operation start];

* 第1行初始化了一个NSBlockOperation对象

* 分别在第5、9、13行通过addExecutionBlock:方法添加了新的操作,包括第1行的操作,一共封装了4个操作

* 在第18行调用start方法后,就会并发地执行这4个操作,也就是会在不同线程中执行

<pre style="margin: 0px; padding: 0px; overflow: auto; white-space: pre; word-wrap: break-word; font-family: &quot;Courier New&quot; !important; font-size: 18px !important;">1 2013-02-02 21:38:46.102 thread[4602:c07]

又执行了1个新的操作,线程:<NSThread: 0x7121d50>{name = (null), num = 1} 2 2013-02-02 21:38:46.102 thread[4602:3f03]

又执行了1个新的操作,线程:<NSThread: 0x742e1d0>{name = (null), num = 5} 3 2013-02-02 21:38:46.102 thread[4602:1b03]

执行第1次操作,线程:<NSThread: 0x742de50>{name = (null), num = 3}

4 2013-02-02 21:38:46.102 thread[4602:1303] 又执行了1个新的操作,线程:<NSThread: 0x7157bf0>{name = (null), num = 4}</pre>

可以看出,每个操作所在线程的num值都不一样,说明是不同线程

## 三、NSOperation的其他用法

### 1.取消操作

operation开始执行之后, 默认会一直执行操作直到完成,我们也可以调用cancel方法中途取消操作

### 2.在操作完成后做一些事情

如果想在一个NSOperation执行完毕后做一些事情,就调用NSOperation的setCompletionBlock方法来设置想做的事情

operation.completionBlock = ^() {

NSLog(@"执行完毕");

}

当operation封装的操作执行完毕后,就会回调Block里面的内容

## 四、自定义NSOperation

如果NSInvocationOperation和NSBlockOperation不能满足需求,我们可以直接新建子类继承NSOperation,并添加任何需要执行的操作。如果只是简单地自定义NSOperation,只需要重载-(void)main这个方法,在这个方法里面添加需要执行的操作。

下面写个子类DownloadOperation来下载图片

### 1.继承NSOperation,重写main方法

#### DownloadOperation.h

#import <Foundation/Foundation.h>

@protocol DownloadOperationDelegate;

@interface DownloadOperation : NSOperation // 图片的url路径

@property (nonatomic, copy) NSString *imageUrl; // 代理

@property (nonatomic, assign) id<DownloadOperationDelegate> delegate;

- (id)initWithUrl:(NSString *)url delegate:(id<DownloadOperationDelegate>)delegate;

@end

// 图片下载的协议

@protocol DownloadOperationDelegate <NSObject>

- (void)downloadFinishWithImage:(UIImage *)image; @end

#### DownloadOperation.m

#import "DownloadOperation.h"

2

3 @implementation DownloadOperation

4 @synthesize delegate = _delegate; //使用@synthesize 只有一个目的——给实例变量起个别名,或者说为同一个变量添加两个名字。

5 @synthesize imageUrl = _imageUrl;

6

7 // 初始化

8 - (id)initWithUrl:(NSString *)url delegate:(id<DownloadOperationDelegate>)delegate {

9    if (self = [super init]) {

10        self.imageUrl = url;

11        self.delegate = delegate;

12 }

13    return self;

14 }

15 // 释放内存

16 - (void)dealloc {

17 [super dealloc];

18 [_imageUrl release];

19 }

20

21 // 执行主任务

22 - (void)main {

23    // 新建一个自动释放池,如果是异步执行操作,那么将无法访问到主线程的自动释放池

24 @autoreleasepool {

25        // ....

26 }

27 }

28 @end

* 在第22行重载了main方法,等会就把下载图片的代码写到这个方法中

* 如果这个DownloadOperation是在异步线程中执行操作,也就是说main方法在异步线程调用,那么将无法访问主线程的自动释放池,所以在第24行创建了一个属于当前线程的自动释放池

### 2.正确响应取消事件

* 默认情况下,一个NSOperation开始执行之后,会一直执行任务到结束,就比如上面的DownloadOperation,默认会执行完main方法中的所有代码。

* NSOperation提供了一个cancel方法,可以取消当前的操作。

* 如果是自定义NSOperation的话,需要手动处理这个取消事件。比如,一旦调用了cancel方法,应该马上终止main方法的执行,并及时回收一些资源。

* 处理取消事件的具体做法是:在main方法中定期地调用isCancelled方法检测操作是否已经被取消,也就是说是否调用了cancel方法,如果返回YES,表示已取消,则立即让main方法返回。

* 以下地方可能需要调用isCancelled方法:

*  在执行任何实际的工作之前,也就是在main方法的开头。因为取消可能发生在任何时候,甚至在operation执行之前。

*  执行了一段耗时的操作之后也需要检测操作是否已经被取消

1 - (void)main {

2    // 新建一个自动释放池,如果是异步执行操作,那么将无法访问到主线程的自动释放池

3    @autoreleasepool {

4        if (self.isCancelled) return;

5

6        // 获取图片数据

7        NSURL *url = [NSURL URLWithString:self.imageUrl];

8        NSData *imageData = [NSData dataWithContentsOfURL:url];

9

10        if (self.isCancelled) {

11            url = nil;

12            imageData = nil;

13            return;

14 }

15

16        // 初始化图片

17        UIImage *image = [UIImage imageWithData:imageData];

18

19        if (self.isCancelled) {

20            image = nil;

21            return;

22 }

23

24        if ([self.delegate respondsToSelector:@selector(downloadFinishWithImage:)]) {

25            // 把图片数据传回到主线程

26            [(NSObject *)self.delegate performSelectorOnMainThread:@selector(downloadFinishWithImage:) withObject:image waitUntilDone:NO];

27 }

28 }

29 }</pre>

* 在第4行main方法的开头就先判断operation有没有被取消。如果被取消了,那就没有必要往下执行了

* 经过第8行下载图片后,在第10行也需要判断操作有没有被取消

* 总之,执行了一段比较耗时的操作之后,都需要判断操作有没有被取消

* 图片下载完毕后,在第26行将图片数据传递给了代理(delegate)对象

 

 

 

 

NSOperation的简单使用的更多相关文章

  1. 3.多线程NSOperation

    1.NSOperation的基本操作 使用NSOperation的两个子类,NSInvocationOperation 和 NSBlockOperation 创建操作,然后将操作添加到队列中去执行 / ...

  2. iOS开发之多线程技术——NSOperation篇

    本篇将从四个方面对iOS开发中使用到的NSOperation技术进行讲解: 一.什么是NSOperation 二.我们为什么使用NSOperation 三.在实际开发中如何使用NSOperation ...

  3. 多线程编程2 - NSOperation

    一.NSOperation 1.简介 NSOperation实例封装了需要执行的操作和执行操作所需的数据,并且能够以并发或非并发的方式执行这个操作. NSOperation本身是抽象基类,因此必须使用 ...

  4. iOS开发多线程--(NSOperation/Queue)

    iOS实现多线程的方式有三种,分别是NSThread.NSOperation.GCD. 关于GCD,请阅读GCD深入浅出学习 简介 NSOperation封装了需要执行的操作和执行操作所需的数据,提供 ...

  5. IOS开发 多线程编程 - NSOperation

    一.NSOperation 1.简介 NSOperation实例封装了需要执行的操作和执行操作所需的数据,并且能够以并发或非并发的方式执行这个操作. NSOperation本身是抽象基类,因此必须使用 ...

  6. 如何使用NSOperations和NSOperationQueues(二)

    "每一个应用程序至少有一个主线程.线程的工作就是去执行一系列的指令.在Cocoa Touch中,主线程包含应用程序的主运行回路.几乎所有你写的代码都会在主线程中执行,除非你特别创建" ...

  7. 如何使用NSOperations和NSOperationQueues 第一部分

    这篇文章还可以在这里找到 英语 学习如何在你的app中使用NSOperations! 这篇博客是由iOS个人开发者Soheil Moayedi Azarpour发布的. 每个人都会在使用iOS或者Ma ...

  8. iOS开发多线程篇—NSOperation简单介绍

    iOS开发多线程篇—NSOperation简单介绍 一.NSOperation简介 1.简单说明 NSOperation的作⽤:配合使用NSOperation和NSOperationQueue也能实现 ...

  9. iOS 多线程 简单学习NSThread NSOperation GCD

    1:首先简单介绍什么叫线程 可并发执行的,拥有最小系统资源,共享进程资源的基本调度单位. 共用堆,自有栈(官方资料说明iOS主线程栈大小为1M,其它线程为512K). 并发执行进度不可控,对非原子操作 ...

随机推荐

  1. 已知数据库中存在表tb_book2,通过在图书信息界面填写书本的基本信息,然后提交后写入数据库中的表格中。需要对提交的信息进行修改,信息填入不能为空,为空则则有提示。

    jsp结合SQLSERVER向数据库中的表添加图书信息. 已知数据库中存在表tb_book2,通过在图书信息界面填写书本的基本信息,然后提交后写入数据库中的表格中.需要对提交的信息进行修改,信息填入不 ...

  2. 齐博x1自定义字段关联其它字段的隐藏显示

    如下图,对于单选\多选\下拉框这种表单类型, 选择某一项后, 你还想他关联其它选项的隐藏或显示,你可以加多一个参数设置处理通常情况,用得最普遍的,就是两项参数,用竖线隔开,比如下面的1|洋房2|别墅 ...

  3. json文本数据

    本文主要针对三个问题:json格式数据,text数据与json数据之间的关系,json和python字典的区别 1.什么是json数据? json是文本数据,可以在网络中传输的通用数据,它是具有特定格 ...

  4. debian如何删除无效的应用图标

    1.看/usr/share/applications下是否有xxx.desktop 2.可以到-/.local/share/applications下看是否有xxx.desktop 来源:https: ...

  5. 论文笔记 - GRAD-MATCH: A Gradient Matching Based Data Subset Selection For Efficient Learning

    Analysis Coreset 是带有权重的数据子集,目的是在某个方面模拟完整数据的表现(例如损失函数的梯度,既可以是在训练数据上的损失,也可以是在验证数据上的损失): 给出优化目标的定义: $w^ ...

  6. 用map来统计数组中各个字符串的数量

    1.背景 想要统计这一个字符串数组中每一个非重复字符串的数量,使用map来保存其key和value.这个需求在实际开发中经常使用到,我以前总是新建一个空数组来记录不重复字符串,并使用计数器计数,效率低 ...

  7. 【题解】CF45I TCMCF+++

    题面传送门 题目描述 有 \(n\) 个数 \(a_i\) 请你从中至少选出一个数,使它们的乘积最大 解决思路 对于正数,对答案一定有贡献(正数越乘越大),所以输入正数时直接输出即可. 对于负数,如果 ...

  8. Vue3 企业级优雅实战 - 组件库框架 - 4 组件库的 CSS 架构

    在前一篇文章中分享了搭建组件库的基本开发环境.创建了 foo 组件模块和组件库入口模块,本文分享组件库的样式架构设计. 1 常见的 CSS 架构模式 常见的 CSS 架构模式有很多:OOCSS.ACS ...

  9. mindxdl--common--head_handler.go

    // Copyright (c) 2021. Huawei Technologies Co., Ltd. All rights reserved.// Package common the commo ...

  10. 【网络】https 轻解读

    Abstract TLS.SSL.摘要(digest).对称/非对称加密.数字签名(signature).证书(certification),傻傻分不清楚?为了解 https, 鄙人对以上这几个名词都 ...