iOS开发-多线程NSOperation和NSOperationQueue

简介:

上一篇文章稍微提及了一下NSThread的使用,NSThread能直观地控制线程对象,不过需要自己管理线程的生命周期,线程同步,用起来比较繁琐,而且比较容易出错。不过Apple给出了自己的解决方案NSOperation,它本身是抽象基类,因此必须使用它的子类,使用NSOperation子类的方式有NSInvocationOperation和NSBlockOperation两种方式,先补充一下NSThread的用法:

NSThread获取当前线程:

1
[ NSThread  currentThread]

 performSelectorInBackground可以更新UI,不建议使用:

1
2
3
4
5
- ( IBAction )update:( id )sender {
 
     [ self  performSelectorInBackground: @selector (changeImage) withObject: nil ];
     
}

图片背景更新:

1
2
3
4
-( void )changeImage{
     NSLog (@ "线程执行完之后更新图片" );
     self .myImageView.image=[UIImage imageNamed:[ NSString  stringWithFormat:@ "Thread2.jpg" ]];
}

NSInvocationOperation和NSBlockOperation

这两种方式都很简单,其中NSInvocation的调用方式类似于NSThread,NSBlockOperation如果对Block有一点了解就可以,如果不明白的可以参考本人之前的Block文章 Object-C-代码块Block回顾,那么接下来的使用方式就很简单:

先来看下NSInvocationOperation的实例化方式:

1
2
3
4
//初始化
NSInvocationOperation  *myInvocationOperation= [[ NSInvocationOperation  alloc] initWithTarget: self  selector: @selector (operationTaskMethod) object: nil ];
//启动
[myInvocationOperation start];

调用方法:

1
2
3
4
-( void )operationTaskMethod{
     NSLog (@ "NSInvocationOperation初始化执行" );
     
}

NSBlockOperation的方式:

1
2
3
4
NSBlockOperation  *blockOperation=[ NSBlockOperation  blockOperationWithBlock:^{
       NSLog (@ "BlockOperation块执行" );
   }];
   [blockOperation start];

两种方式很方便,这个时候可以使用NSOperationQueue作为一个队列将线程包含在一起,首先定义一个NSOperationQuene:

1
@property  (strong, nonatomic NSOperationQueue  *myOperationQuene;

 这个时候需要调用:

1
2
3
4
5
6
7
8
9
10
11
NSInvocationOperation  *myInvocationOperation= [[ NSInvocationOperation  alloc] initWithTarget: self  selector: @selector (operationTaskMethod) object: nil ];
 
NSBlockOperation  *blockOperation=[ NSBlockOperation  blockOperationWithBlock:^{
     NSLog (@ "BlockOperation块执行" );
}];
 
self .myOperationQuene=[[ NSOperationQueue  alloc]init];
 
[ self .myOperationQuene addOperation:myInvocationOperation];
 
[ self .myOperationQuene addOperation:blockOperation];

 上面最后的结果不确定,线程执行的顺序没法确定,如果想确定的按照顺序执行,需要添加一个依赖:

1
[blockOperation addDependency:myInvocationOperation];

  添加依赖之后的,每次输出的结果一定是这样的:

1
2
2015-02-11 07:56:13.457 ThreadDemo[657:15033]  NSInvocationOperation 初始化执行
2015-02-11 07:56:13.457 ThreadDemo[657:15034] BlockOperation块执行

 自定义NSOperation

每次一看到自定义,就感觉瞬间有了档次,然后参考一下前人的经验,不过网上的博客有的不好说,那感觉就是我想吃一个鸡腿,却拿到了一个鸡腿堡,需要的不需要的都要自己一起吸收。NSInvocationOperation和NSBlockOperation这两种方式不能满足业务需求,这个时候需要自定义的NSOperation,自定义的有两种分为非并发(NonConcurrent)和并发(Concurrent)两种形式,本文介绍非并发形式。

新建一个继承自NSOperation的MyCustomOperation,然后实现一下main方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//
//  MyCustomOperation.h
//  ThreadDemo
//
//  Created by keso on 15/2/11.
//  Copyright (c) 2015年 keso. All rights reserved.
//
 
#import <Foundation/Foundation.h>
 
@interface  MyCustomOperation :  NSOperation
 
@property  (strong, nonatomic NSString   *customdata;
 
-( void )initData:( NSString  *)data;
 
@end

NSOperation对象需要定期地调用isCancelled方法检测操作是否已经被取消,如果返回YES(表示已取消),则立即退出执行回收内存资源。所有NSOperation子类,一般用于代码比较容易终止的地方, 在循环的每次迭代过程中,如果每个迭代相对较长可能需要调用多次和没有执行工作之前调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//
//  MyCustomOperation.m
//  ThreadDemo
//
//  Created by keso on 15/2/10.
//  Copyright (c) 2015年 keso. All rights reserved.
//
 
#import "MyCustomOperation.h"
 
@implementation  MyCustomOperation
 
- ( void )initData:( NSString  *)data{
     if  ( self  ==[ super  init])
         _customdata= data;
}
- ( void )main {
     @try  {
         BOOL  isDone =  NO ;
         NSLog (@ "循环之前的调用" );
         while  (![ self  isCancelled] && !isDone) {
             // Do some work and set isDone to YES when finished
             NSLog (@ "已经运行成功了" );
             isDone= YES ;
         }
     }
     @catch (...) {
         NSLog (@ "出现异常,请检查代码~" );
     }
}
 
@end

如果需要调用定义的NSOPeration实例化之后Start即可:

1
2
MyCustomOperation *customOperation=[[MyCustomOperation alloc] init];
  [customOperation start];

本文转自Fly_Elephant博客园博客,原文链接:http://www.cnblogs.com/xiaofeixiang/p/4285102.html,如需转载请自行联系原作者

相关文章
|
22天前
|
API Android开发 iOS开发
安卓与iOS开发中的线程管理对比
【9月更文挑战第12天】在移动应用的世界中,安卓和iOS平台各自拥有庞大的用户群体。开发者们在这两个平台上构建应用时,线程管理是他们必须面对的关键挑战之一。本文将深入探讨两大平台在线程管理方面的异同,通过直观的代码示例,揭示它们各自的设计理念和实现方式,帮助读者更好地理解如何在安卓与iOS开发中高效地处理多线程任务。
|
2月前
|
安全 测试技术 调度
iOS开发-多线程编程
【8月更文挑战第12天】在iOS开发中,属性的内存管理至关重要,直接影响应用性能与稳定性。主要策略包括:`strong`(强引用),保持对象不被释放;`weak`(弱引用),不保持对象,有助于避免循环引用;`assign`(赋值),适用于基本数据类型及非指针对象类型;`copy`(复制),复制对象而非引用,确保不变性。内存管理基于引用计数,利用自动引用计数(ARC)自动管理对象生命周期。此外,需注意避免循环引用,特别是在block中。最佳实践包括理解各策略、避免不必要的强引用、及时释放不再使用的对象、注意block中的内存管理,并使用工具进行内存分析。正确管理内存能显著提升应用质量。
|
2月前
|
安全 网络安全 数据安全/隐私保护
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享安卓与iOS开发中的线程管理比较
【8月更文挑战第30天】本文将探讨网络安全与信息安全的重要性,并分享关于网络安全漏洞、加密技术和安全意识的知识。我们将了解常见的网络攻击类型和防御策略,以及如何通过加密技术和提高安全意识来保护个人和组织的信息安全。
|
2月前
|
编译器 C语言 iOS开发
iOS 16 系统键盘修复问题之确定_lock是否用于保护对_deferredTasks的多线程读写如何解决
iOS 16 系统键盘修复问题之确定_lock是否用于保护对_deferredTasks的多线程读写如何解决
|
iOS开发
iOS多线程之NSOperationQueue-依赖、并发数、优先级、自定义Operation等最全的使用总结
iOS多线程之NSOperationQueue-依赖、并发数、优先级、自定义Operation等最全的使用总结
394 0
|
5月前
|
iOS开发
多线程和异步编程:解释 iOS 中的同步和异步任务的概念。
多线程和异步编程:解释 iOS 中的同步和异步任务的概念。
116 1
|
5月前
|
API 调度 iOS开发
多线程和异步编程:什么是 GCD(Grand Central Dispatch)?如何在 iOS 中使用 GCD?
多线程和异步编程:什么是 GCD(Grand Central Dispatch)?如何在 iOS 中使用 GCD?
60 1
|
iOS开发
iOS多线程编程之二——NSOperation与NSOperationQueue(二)
iOS多线程编程之二——NSOperation与NSOperationQueue
130 0
|
iOS开发
iOS多线程编程之二——NSOperation与NSOperationQueue(一)
iOS多线程编程之二——NSOperation与NSOperationQueue
152 0