转 ios中的几种多线程实现 .

iOS 支持多个层次的多线程编程,层次越高的抽象程度越高,使用起来也越方便,也是苹果最推荐使用的方法。下面根据抽象层次从低到高依次列出iOS所支持的多线程编程范式:
1,
Thread;
2,
Cocoa operations;
3,
Grand Central Dispatch (GCD) (iOS4 才开始支持)

下面简要说明这三种不同范式:
Thread
是这三种范式里面相对轻量级的,但也是使用起来最负责的,你需要自己管理thread的生命周期,线程之间的同步。线程共享同一应用程序的部分内存空间,它们拥有对数据相同的访问权限。你得协调多个线程对同一数据的访问,一般做法是在访问之前加锁,这会导致一定的性能开销。在
iOS 中我们可以使用多种形式的 thread:
Cocoa
threads: 使用NSThread 或直接从 NSObject 的类方法 performSelectorInBackground:withObject:
来创建一个线程。如果你选择thread来实现多线程,那么 NSThread 就是官方推荐优先选用的方式。
POSIX
threads: 基于 C 语言的一个多线程库,

Cocoa
operations是基于 Obective-C实现的,类 NSOperation
以面向对象的方式封装了用户需要执行的操作,我们只要聚焦于我们需要做的事情,而不必太操心线程的管理,同步等事情,因为NSOperation已经为我们封装了这些事情。
NSOperation 是一个抽象基类,我们必须使用它的子类。iOS 提供了两种默认实现:NSInvocationOperation 和
NSBlockOperation。

Grand
Central Dispatch (GCD): iOS4 才开始支持,它提供了一些新的特性,以及运行库来支持多核并行编程,它的关注点更高:如何在多个 cpu
上提升效率。

有了上面的总体框架,我们就能清楚地知道不同方式所处的层次以及可能的效率,便利性差异。下面我们先来看看
NSThread 的使用,包括创建,启动,同步,通信等相关知识。这些与 win32/Java 下的 thread 使用非常相似。

线程创建与启动
NSThread的创建主要有两种直接方式:
[NSThread
detachNewThreadSelector:@selector(myThreadMainMethod:) toTarget:self
withObject:nil];

NSThread*
myThread = [[NSThread alloc] initWithTarget:self
 
                                     
selector:@selector(myThreadMainMethod:)
 
                                      object:nil];
[myThread
start];

这两种方式的区别是:前一种一调用就会立即创建一个线程来做事情;而后一种虽然你
alloc 了也 init了,但是要直到我们手动调用 start
启动线程时才会真正去创建线程。这种延迟实现思想在很多跟资源相关的地方都有用到。后一种方式我们还可以在启动线程之前,对线程进行配置,比如设置 stack
大小,线程优先级。

还有一种间接的方式,更加方便,我们甚至不需要显式编写
NSThread 相关代码。那就是利用 NSObject 的类方法 performSelectorInBackground:withObject:
来创建一个线程:
[myObj
performSelectorInBackground:@selector(myThreadMainMethod)
withObject:nil];
其效果与
NSThread 的 detachNewThreadSelector:toTarget:withObject: 是一样的。

线程同步
线程的同步方法跟其他系统下类似,我们可以用原子操作,可以用
mutex,lock等。
iOS的原子操作函数是以
OSAtomic开头的,比如:OSAtomicAdd32, OSAtomicOr32等等。这些函数可以直接使用,因为它们是原子操作。

iOS中的
mutex 对应的是 NSLock,它遵循 NSLooking协议,我们可以使用 lock, tryLock, lockBeforeData:来加锁,用
unLock来解锁。使用示例:
BOOL
moreToDo = YES;
NSLock
*theLock = [[NSLock alloc] init];
...
while
(moreToDo) {
 
  /* Do another increment of calculation */
 
  /* until there’s no more to do. */
 
  if ([theLock tryLock]) {
 
      /* Update display used by all threads. */
 
      [theLock unlock];
 
  }
}

我们可以使用指令
@synchronized 来简化 NSLock的使用,这样我们就不必显示编写创建NSLock,加锁并解锁相关代码。
-
(void)myMethod:(id)anObj
{
 
  @synchronized(anObj)
 
  {
 
      // Everything between the braces is protected by the @synchronized
directive.
 
  }
}
 
还有其他的一些锁对象,比如:循环锁NSRecursiveLock,条件锁NSConditionLock,分布式锁NSDistributedLock等等,在这里就不一一介绍了,大家去看官方文档吧。

用NSCodition同步执行的顺序
NSCodition
是一种特殊类型的锁,我们可以用它来同步操作执行的顺序。它与 mutex 的区别在于更加精准,等待某个 NSCondtion 的线程一直被
lock,直到其他线程给那个 condition 发送了信号。下面我们来看使用示例:

某个线程等待着事情去做,而有没有事情做是由其他线程通知它的。

[cocoaCondition
lock];
while
(timeToDoWork <= 0)
 
  [cocoaCondition wait];
 
timeToDoWork--; 
//
Do real work here.
[cocoaCondition
unlock];

其他线程发送信号通知上面的线程可以做事情了:
[cocoaCondition
lock];
timeToDoWork++;
[cocoaCondition
signal];
[cocoaCondition
unlock];

线程间通信
线程在运行过程中,可能需要与其它线程进行通信。我们可以使用
NSObject 中的一些方法:
在应用程序主线程中做事情:
performSelectorOnMainThread:withObject:waitUntilDone:
performSelectorOnMainThread:withObject:waitUntilDone:modes:

在指定线程中做事情:
performSelector:onThread:withObject:waitUntilDone:
performSelector:onThread:withObject:waitUntilDone:modes:

在当前线程中做事情:
performSelector:withObject:afterDelay:
performSelector:withObject:afterDelay:inModes:

取消发送给当前线程的某个消息
cancelPreviousPerformRequestsWithTarget:
cancelPreviousPerformRequestsWithTarget:selector:object:

如在我们在某个线程中下载数据,下载完成之后要通知主线程中更新界面等等,可以使用如下接口:-
(void)myThreadMainMethod
{
 
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 
  // to do something in your thread job
 
  ...
 
  [self performSelectorOnMainThread:@selector(updateUI) withObject:nil
waitUntilDone:NO];
 
  [pool release];
}

RunLoop
说到
NSThread 就不能不说起与之关系相当紧密的 NSRunLoop。Run loop 相当于 win32
里面的消息循环机制,它可以让你根据事件/消息(鼠标消息,键盘消息,计时器消息等)来调度线程是忙碌还是闲置。
系统会自动为应用程序的主线程生成一个与之对应的
run loop 来处理其消息循环。在触摸 UIView 时之所以能够激发 touchesBegan/touchesMoved
等等函数被调用,就是因为应用程序的主线程在 UIApplicationMain 里面有这样一个 run loop 在分发 input 或 timer
事件。

参考资料:
NSRunLoop概述和原理:http://xubenyang.me/384

官方文档:http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Multithreading/

转载至:

http://blog.csdn.net/kesalin/article/details/6698146

时间: 2024-10-11 13:02:12

转 ios中的几种多线程实现 .的相关文章

ios中的几种多线程实现

iOS 支持多个层次的多线程编程,层次越高的抽象程度越高,使用起来也越方便,也是苹果最推荐使用的方法.下面根据抽象层次从低到高依次列出iOS所支持的多线程编程范式:1, Thread;2, Cocoa operations;3, Grand Central Dispatch (GCD) (iOS4 才开始支持)下面简要说明这三种不同范式:Thread 是这三种范式里面相对轻量级的,但也是使用起来最负责的,你需要自己管理thread的生命周期,线程之间的同步.线程共享同一应用程序的部分内存空间,它

IOS开发数据存储篇—IOS中的几种数据存储方式

IOS开发数据存储篇—IOS中的几种数据存储方式 发表于2016/4/5 21:02:09  421人阅读 分类: 数据存储 在项目开发当中,我们经常会对一些数据进行本地缓存处理.离线缓存的数据一般都保存在APP所在的沙盒之中.一般有以下几种: 1.PList(XML属性列表) 在使用plist进行数据存储和读取,只适用于系统自带的一些常用类型才能用,且必须先获取路径相对麻烦 //写入文件 NSString *doc = [NSSearchPathForDirectoriesInDomains(

iOS中的两种主要架构及其优缺点

凡是程序的开发者,应该对程序的架构都不陌生.一个程序的架构的好坏对这个程序有着非常重要的作用.今天我们来看一下iOS开发中用要的两种主流的程序架构.这个过程中我们主要以例子的形式展开. 我们来看第一种架构:如下图所示: 这种程序的架构主要原理是创建了一个导航控制器来控制页面之间的切换.这种架构一般把主界面作为导航控制器的根视图控制器.在上图所求的程序架构中,主界面管理了四个界面:微信界面,发现界面,联系人界面,关于我界面.如果程序是第一次运行的时候,进入用户指引界面,然后进入登录界面,输入账户名

iOS中的几种指令集(armv6、armv7、armv7s、arm64)

目前iOS的指令集有以下几种: armv6 iPhone iPhone2 iPhone3G 第一代和第二代iPod Touch armv7 iPhone4 iPhone4S armv7s iPhone5 iPhone5C arm64 iPhone5S 机器对指令集的支持是向下兼容的,因此armv7的指令集是可以运行在iPhone5S的,只是效率没那么高而已~ ================================================ Architecture : 指你想支持

iOS中面试题之----多线程

1.多线程的底层实现 (1)首先回答什么是线程 1个进程要想执行任务,必须得有线程.线程是进程的基本执行单元,一个进程(程序)的所有任务都在线程中执行 (2)什么是多线程 1个进程中可以开启多条线程,每条线程可以并行(同时)执行不同的任务. 多线程的作用:更新显示UI界面.处理用户触摸事件. (3)Mach是第一个以多线程方式处理任务的系统,因此多线程的底层实现机制是基于Mach的线程. (4)开发中实现多线程的方案 1>C语言的POSIX接口:#include<pthread.h> 2

Android中的几种多线程实现

有以下几种方式: 1)Activity.runOnUiThread(Runnable) 2)View.post(Runnable) ;View.postDelay(Runnable , long) 3)Handler 4)AsyncTask Android是单线程模型,这意味着Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行,所以你单纯的new一个Thread并且start()是不行的,因为这违背了Android的单线程模型.那么如何用好多线程呢?总结一下: 事件处理的原

ios中的三种弹框

目前为止,已经知道3种IOS弹框: 1.系统弹框-底部弹框 UIActionSheet (1)用法:处理用户非常危险的操作,比如注销系统等 (2)举例: UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"确定要注销?" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:@"确定" otherButton

对比iOS中的四种数据存储

你是用什么方法来持久保存数据的?这是在几乎每一次关于iOS技术的交流或讨论都会被提到的问题,而且大家对这个问题的热情持续高涨.本文主要从概念上把“数据存储”这个问题进行剖析,并且结合各自特点和适用场景给大家提供一个选择的思路,并不详细介绍某一种方式的技术细节. 谈到数据储存,首先要明确区分两个概念,数据结构和储存方式.所谓数据结构就是数据存在的形式.除了基本的NSDictionary.NSArray和NSSet这些对象,还有更复杂的如:关系模型.对象图和属性列表多种结构.而存储方式则简单的分为两

iOS中通过GCD实现多线程用法

GCD简介 GCD全称Grand Central Dispatch,可翻译为“牛逼的中枢调度器”. 纯C语言,提供了非常多强大的函数. GCD优势: GCD是苹果公司为多核的并行运算提出的解决方案. GCD会自动利用更多的CPU内核(比如双核.四核). GCD会自动管理线程的生命周期(创建线程.调度任务.销毁线程). 程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码. 任务和队列 GCD中有2个核心概念 任务:执行什么操作. 队列:用来存放任务. GCD的使用就2个步骤 定制任