在Object-c中,常用的多线程处理类分别为NSThread和NSOperationQueue。使用这两个类处理多线程,让复杂的多线程处理变得简单高效。下面分别介绍。

一、NSThread类

苹果公司的Cocoa框架共支持三种多线程机制,分别为NSThread、GCD(Grand Central Dispatch)、Cocoa NSOperatio。NSThree是官方推荐的线程处理方式,它在处理机制上,需要开发者负责手动管理Thread的生命周期,包括子线程与主线程之间的同步等。线程共享同一应用程序的部分内存空间,它们拥有对数据相同的访问权限。你得协调多个线程 对同一数据的访问,一般做法是在访问之前加锁,这会导致一定的性能开销。在 iOS 中我们可以使用多种形式的 thread。初次接触的读者也许会觉得生涩,但事实上NSThread类已经提供了完善的接口,在使用方式上并不会太难。使用NSTread管理线程,主要的步骤如下。

1)声明一个NSCondition同步锁;

2)声明若干个NSThread子线程;

3)指定NSThread子线程的目标指行方法(可以在构造函数中指定);

4)设置子线程的名称;

5)star启动子线程。

其中,子线程的执行方法一般只需要一个共同方法即可(可以通过线程名,分辨当前的执行线程)。下面通过代码演示NSThread类的使用。假设我们需要下载网络图片,在非异步形式的情况下,IOS界面必须等到图片下载完毕后,UI才会反应。这时利用多线程就可以达到异步下载的效果。

ViewController1.h

#import <UIKit/UIKit.h>
@interface ViewController1 : UIViewController{NSCondition *_condition;NSThread *_thread_1;NSThread *_thread_2;
}
@end

ViewController1.m

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

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

/
//  ViewController1.m
//  Thread_demo
//
//  Created by MAC on 13-4-22.
//  Copyright (c) 2013年 李开涌. All rights reserved.
//
#import "ViewController1.h"
@interface ViewController1 ()
@end
@implementation ViewController1
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];if (self) {// Custom initializationself.title=@"多线程NSThread";}return self;
}
- (void)viewDidLoad
{[super viewDidLoad];//创建一个进程锁,实现线程同步_condition=[[NSCondition alloc] init];//创建线程1_thread_1=[[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil];[_thread_1 setName:@"thread_1"];[_thread_1 start];//创建线程2_thread_2=[[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil];[_thread_2 setName:@"thread_2"];[_thread_2 start];}
#pragma mark--线程执行方法
-(void)run{//进程上锁[_condition lock];NSLog(@"运行的线程名:%@",[[NSThread currentThread]name]);if ([[[NSThread currentThread]name] isEqualToString:@"thread_1"]) {NSLog(@"111");NSURL *p_w_picpathUrl_1=[NSURL URLWithString:@"http://t.beauty-soft.net/upload/ceiba20130224_014522_8679.jpg"];NSData *data_1=[NSData dataWithContentsOfURL:p_w_picpathUrl_1];UIImage *p_w_picpath_1=[UIImage p_w_picpathWithData:data_1];UIImageView *p_w_picpathView_1=[[UIImageView alloc] initWithImage:p_w_picpath_1];p_w_picpathView_1.frame=CGRectMake(60, 20, 200, 200);[self.view addSubview:p_w_picpathView_1];[p_w_picpathView_1 release];}else if([[[NSThread currentThread]name] isEqualToString:@"thread_2"]){NSLog(@"222");NSURL *p_w_picpathUrl_2=[NSURL URLWithString:@"http://t.beauty-soft.net/upload/ceiba20120704_121437_3455.jpg"];    NSData *data_2=[NSData dataWithContentsOfURL:p_w_picpathUrl_2];UIImage *p_w_picpath_2=[UIImage p_w_picpathWithData:data_2];UIImageView *p_w_picpathView_2=[[UIImageView alloc] initWithImage:p_w_picpath_2];p_w_picpathView_2.frame=CGRectMake(60, 250, 200, 200);[self.view addSubview:p_w_picpathView_2];[p_w_picpathView_2 release];}//解锁[_condition unlock];}
-(void)dealloc{[_thread_1 release];[_thread_2 release];[_condition release];[super dealloc];
}
- (void)didReceiveMemoryWarning
{[super didReceiveMemoryWarning];// Dispose of any resources that can be recreated.
}
@end

二、NSOperationQueue类

如果需要让线程同时并行运行多个,可以将线程加入队列(Queue)中,NSOperationQueue类就是一个线程队列管理类,他提供了线程并行、队列的管理。可以认为NSOperationQueue就是一个线程管理器,通过addOperations方法,我们可以一次性把多个(数组形式)线程添加到队列中。同时,NSOperationQueue允许通过setMaxConcurrentOperationCount方法设置队列的并行(同一时间)运行数量。NSOperationQueue的使用步骤如下。

1)声明一个NSOperationQueue对象;

2)声明若干个NSInvocationOperation子线程对象,并指定回调方法;

3)将NSInvocationOperation子线程添加到数组;

4)把数组赋给NSOperationQueue类中的addOperations方法;

5) 实现回调方法;

6)在回调方法中实现performSelectorOnMainThread方法,更新主线程上的界面UI元素。

下面,使用NSOperationQueue类,实现前面NSThread类相同的功能(即下载图片)。代码如下。

ViewController2.m

//

//  ViewController2.m
//  Thread_demo
//
//  Created by MAC on 13-4-22.
//  Copyright (c) 2013年 李开涌. All rights reserved.
//
#import "ViewController2.h"
@interface ViewController2 ()
@end
@implementation ViewController2
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];if (self) {// Custom initializationself.title=@"线程队列";}return self;
}
- (void)viewDidLoad
{[super viewDidLoad];// 线程队列管理器,实现线程并行运行_opeartionQueue=[[NSOperationQueue alloc] init];//队列最大同时运行数量[_opeartionQueue setMaxConcurrentOperationCount:1];tags=20;//创建线程1NSInvocationOperation *invocationOpearation_1=[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run:) object:@"http://t.beauty-soft.net/upload/ceiba20130224_014522_8679.jpg"] autorelease];//创建线程2NSInvocationOperation *invocationOpearation_2=[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run:) object:@"http://t.beauty-soft.net/upload/ceiba20120704_121437_3455.jpg"] autorelease];NSArray *array=@[invocationOpearation_1,invocationOpearation_2];//把程序添加到管理器中[_opeartionQueue addOperations:array waitUntilFinished:YES];
}
-(void)run:(NSString *)p_w_picpathStrinUrl{NSLog(@"%@",[_opeartionQueue operations]);NSLog(@"mainQueue%@",[NSOperationQueue mainQueue]);NSLog(@"i==%i",tags);NSLog(@"urlStr:%@",p_w_picpathStrinUrl);NSURL *url=[NSURL URLWithString:p_w_picpathStrinUrl];NSData *data=[NSData dataWithContentsOfURL:url];UIImage *p_w_picpath=[UIImage p_w_picpathWithData:data];UIImageView *p_w_picpathView=[[[UIImageView alloc] initWithImage:p_w_picpath]autorelease];p_w_picpathView.frame=CGRectMake(60, tags, 200, 200);tags+=200;//通知主线程更新UI[self performSelectorOnMainThread:@selector(updateUI:) withObject:p_w_picpathView waitUntilDone:NO];}
-(void)updateUI:(UIImageView *)p_w_picpathView{[self.view addSubview:p_w_picpathView];}
- (void)dealloc
{[_opeartionQueue release];[super dealloc];
}
- (void)didReceiveMemoryWarning
{[super didReceiveMemoryWarning];// Dispose of any resources that can be recreated.
}
@end

[self performSelectorOnMainThread:@selector(updateLabel:)withObject:updateData waitUntilDone:YES]; 该方法是一个主线程同步方法,不仅可以应用在NSOpeartionQueue中,同样还适用于NSThread类。

Grand Central Dispatch,或者简称 GCD,是一个与 Block Object 产生工作的低级的 C API。GCD 真正的用途是将任务分配到多个核心又不让程序员担心哪个内核执行哪个任务。 在 Max OS X 上,多内核设备,包括笔记本,用户已经使用了相当长的时间。通过多核设备 比如 iPad2 的介绍,程序员能为 iOS 写出神奇的多核多线程 APP。

一、线程管理常用方法


1.performSelector(InBackground or MainThread)
这个方法比较方便,但是问题在于参数传递只能支持一个对象(传多个参数,我是将其打包在一个NSDictionary里面)
2.NSOperationQueue
这个方法稍微复杂,提供了每个任务的封装(NSOperation)。可以继承NSOperation之后,在main函数中写一些同步执行的代码,然后放到一个Queue之中,Queue自动管理Operation的执行和调度(在UI线程以外)。对于异步执行的代码,需要重载NSOperation的好几个函数才能正常工作(告诉Queue关于这个任务的进度以及执行情况)。
3.NSThread
轻量级的线程管理机制
4.GCD
在UI线程和其它线程之间切换很方便,可以和NSOperationQueue搭配使用。本文着重介绍这个方法。

5,pthread

二、GCD使用示例

GCD 的核心是分派队列。不论在 iOS 还是 Max OS X 分派队列,正如我们快看到的是 由位于主操作系统的 GCD 来管理的线程池。你不会直接与线程有工作关系。你只在分派队 列上工作,将任务分派到这个队列上并要求队列来调用你的任务。GCD 为运行任务提供了 几个选择:同步执行、异步执行和延迟执行等。

1、网络下载

以点击一个按钮,然后显示loading,同时在后台下载一张图片,最后将下载的图片放到UIImageView中显示为例。

//

显示loadingself.indicator.hidden = NO;[self.indicator startAnimating];//进入异步线程dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{//异步下载图片NSURL * url = [NSURL URLWithString:@"http://anImageUrl"];NSData * data = [NSData dataWithContentsOfURL:url];//网络请求之后进入主线程dispatch_async(dispatch_get_main_queue(), ^{//关闭loading[self.indicator stopAnimating];self.indicator.hidden = YES;if (data) {//显示图片self.p_w_picpathView.p_w_picpath = [UIImage p_w_picpathWithData:data];}});});

2、延迟执行

//

延迟2秒执行:double delayInSeconds = 2.0;dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);dispatch_after(popTime, dispatch_get_main_queue(), ^(void){// code to be executed on the main queue after delay});

3、自定义GCD

可以使用dispatch_queue_create函数创建自定义的GCD

dispatch_queue_t custom_queue = dispatch_queue_create(“customQueue”, NULL);dispatch_async(custom_queue, ^{//doing something in custom_queue});dispatch_release(custom_queue);

4、线程合并

利用GCD并行多个线程并且等待所有线程结束之后再执行其它任务

dispatch_group_t group = dispatch_group_create();dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{// 并行执行的线程一});dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{// 并行执行的线程二});dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^{// 汇总结果});

转载于:https://blog.51cto.com/liuyafang/1580134

IOS多线程处理 三种多线程的实例相关推荐

  1. iOS- NSThread/NSOperation/GCD 三种多线程技术的对比及实现

    1.iOS的三种多线程技术 1.NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程) 2.以下两点是苹果专门开发的"并发"技术,使得程序员可以不再去关心 ...

  2. java的如何创建js_[Java教程]JS创建事件的三种方式(实例)

    [Java教程]JS创建事件的三种方式(实例) 0 2016-05-11 14:00:16 1.普通的定义方式 οnclick="Sfont=prompt('请在文本框中输入红色','红色' ...

  3. ios中三种随机数方法

    ios 有如下三种随机数方法: //第一种 srand((unsigned)time(0)); //不加这句每次产生的随机数不变 int i = rand() % 5; //第二种 srandom(t ...

  4. JAVA三种多线程实现方法和应用总结

    最近在做代码优化时学习和研究了下JAVA多线程的使用,看了菜鸟们的见解后做了下总结. 1.JAVA多线程实现方式 JAVA多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用E ...

  5. ios13修改dns都用什么服务器,IOS下三种DNS解析方式分析(LocalDns)

    背景 最近在做iOS的DNS解析,顺便研究了下iOS端本地的DNS解析方式(localDNS),也就是不依赖Http请求,而是用原始的API进行解析,虽然有HttpDNS但是考虑到成本.第三方服务稳定 ...

  6. mysql工厂模式_设计模式-三种工厂模式实例

    1.简单工厂模式:代替new产生对象,产品的类型比较少时. 我们要获得三种不同的数据库对象,如Mysql,SQLserver,Oracle,它们拥有共同的特征,即可以进行抽象,简单工厂目的是将获得具体 ...

  7. iOS用三种途径实现一方法有多个返回值

    以前觉得这种标题有点偏向于理论,实际开发中怎么会有这种诡异的需求,但是真正遇到了这种硬需求时觉得还是有那么点价值的,理论付诸了实践在此也就做了个整理. 以我私下开发中的一处代码为例,本意是希望有这么一 ...

  8. java二维数组三种初始化方法(实例)

    初始化方法: 1.使用大括号直接赋值,适合已经确定知道数组元素的情况 2.给定二维数组的大小 3.数组第二维的长度可变化,未改变 代码举例如下: public class NewArray {publ ...

  9. Java8——三种多线程方式

    2019独角兽企业重金招聘Python工程师标准>>> 1.多线程的使用方式 1.1.继承Thread类 继承Thread并重写run()方法,Thread类中的start方法会去调 ...

  10. iOS钥匙串三种提取方案【iOS加密备份】【keychain_dumper】【frida-objection】

    iOS钥匙串(keychain)是iOS操作系统提供的一种安全存储机制,用于存储用户的敏感信息(如密码等).钥匙串管理器可以在任何应用和扩展中安全地存储和访问用户的敏感信息,而不会被其他应用的访问或破 ...

最新文章

  1. 后BERT时代:15个预训练模型对比分析与关键点探索(附链接)
  2. CALayer 了解与使用
  3. spring心得5--构造器注入@设置控制@案例加注解剖析
  4. Nginx uWsgi Django环境搭建
  5. springmvc重定向到另一个项目_SpringMVC——redirect重定向跳转传值
  6. mysql load会锁表吗_Mysql必读MySQL中由load data语句引起死锁的解决案例
  7. Linux的概念与体系 7. Linux进程基础(转载)
  8. [洛谷P5068][Ynoi2015]我回来了
  9. 牛客练习赛21:A. 黑妹的游戏I
  10. 区块链 solana TPS吞吐率
  11. 车牌识别计算机应用领域,车牌识别全方位应用 引领智能交通新趋势
  12. MySQL数据库环境变量设置
  13. 串口通信以及波特率计算方法
  14. C语言数据结构理解语句L = (LNode * )malloc(sizeof(LNode));
  15. python中Pandas之DataFrame索引、选取数据
  16. Hunter’s Apprentice (猎人的学徒)——【Green 公式( 判断多边形边界曲线顺/逆时针】
  17. SQL_Injection_Base_by_Silic读书摘要
  18. 企业网站首页设计常见的6种布局方式
  19. Python中strip用法
  20. win7安装IIS教程 win7安装IIS 教程win7 安装IIS教程

热门文章

  1. vba连接mysql前的准备_VBA连接MYSQL数据库方法及案例
  2. jQuery基础(鼠标事件,表单事件,键盘事件,自定义事件 篇)
  3. 菜鸟学python集训云_菜鸟学Python,老司机给新手总结的Python实战问题
  4. java 自定义表单 动态表单 表单设计器 工作流引擎 flowable 设计方案
  5. 图灵程序设计丛书 算法(第4版)pdf
  6. OpenGL超级宝典(第7版)之VS2019使用sb7框架搭建自己的程序
  7. netstat命令详解
  8. vbs无限循环代码_vbs整人代码
  9. CCNA学习指南 第八章 下载
  10. AutoCAD2012从入门到精通中文视频教程 第13课 正多边形(个人收藏)