OS 支持多个层次的多线程 编程,层次越高的抽象程度越高,使用起来也越方便,也是苹果最推荐使用的方法。 
 
 
下面简要说明这三种不同范式:  
Thread 是这三种范式里面相对轻量级的,但也是使用起来最负责的,你需要自己管理thread的生命周期,线程 之间的同步。线程 共享同一应用程序的部分内存空间,它们拥有对数据相同的访问权限。 
你得协调多个线程 对同一数据的访问,一般做法是在访问之前加锁,这会导致一定的性能开销。在 iOS 中我们可以使用多种形式的 thread: 
Cocoa threads: 使用NSThread 或直接从 NSObject 的类方法 performSelectorInBackground:withObject: 来创建一个线程 。如果你选择thread来实现多线程 ,那么 NSThread 就是官方推荐优先选用的方式。 
POSIX threads: 基于 C 语言的一个多线程 库, 
 
Cocoa operati*****是基于 Obective-C实现的,类 NSOperation 以面向对象的方式封装了用户需要执行的操作,我们只要聚焦于我们需要做的事情,而不必太操心 线程 的管理,同步等事情, 
因为NSOperation已经为我们封装了这些事情。 NSOperation 是一个抽象基类,我们必须使用它的子类。iOS 提供了两种默认实现:NSInvocationOperation 和 NSBlockOperation。 
 
Grand Central Dispatch : 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 事件。

[iOS]深入浅出 iOS 之多线程 NSThread的更多相关文章

  1. iOS开发:Swift多线程NSThread的使用

    一:创建线程,NSThread创建线程常用的三种方式: //1:手动创建启动 let thread:NSThread = NSThread(target: self, selector:"d ...

  2. 【转】深入浅出 iOS 之生命周期

    [iOS]深入浅出 iOS 之生命周期 深入浅出 iOS 之生命周期  http://blog.csdn.net/kesalin/article/details/6691766 罗朝辉(http:// ...

  3. iOS的三种多线程技术NSThread/NSOperation/GCD

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

  4. IOS 多线程 NSThread

    一个正在运行的应用程序是一个进程,一个进程会默认开启一个主线程,但是在主线程中的操作是串行的,也就是当有多个任务同时需要完成的时候,是按照顺序一个个执行.因此,为了提高效率,会在进程中开启多个线程,每 ...

  5. iOS多线程 NSThread/GCD/NSOperationQueue

    无论是GCD,NSOperationQueue或是NSThread, 都没有线程安全 在需要同步的时候需要使用NSLock或者它的子类进行加锁同步 "] UTF8String], DISPA ...

  6. (转)深入浅出 iOS 之生命周期

    原文:http://www.cocoachina.com/applenews/devnews/2011/0817/3129.html 深入浅出 iOS 之生命周期 发布于:2011-08-17 10: ...

  7. Objective-C 高级编程:iOS与OS X多线程和内存管理

    <Objective-C 高级编程:iOS与OS X多线程和内存管理> 基本信息 原书名: Pro Multithreading and Memory Management for iOS ...

  8. iOS开发网络篇—多线程断点下载

    iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时开启多条线程下载一个较大的文件.因为实现过程较为复杂,所以下面贴出完整的代码. 实现思路:下载开始, ...

  9. 深入浅出--iOS的TCP/IP协议族剖析&&Socket

    深入浅出--iOS的TCP/IP协议族剖析&&Socket   简介 该篇文章主要回顾--TCP/IP协议族中的TCP/UDP.HTTP:还有Socket.(--该文很干,酝酿了许久! ...

随机推荐

  1. SQL 如果存在就更新,如果不存在就添加,使用 Merge 函数(SQL2008版本及以上)

    USE [NationalUnion] GO /****** Object: StoredProcedure [dbo].[proc_DataSummary] Script Date: 07/03/2 ...

  2. tomcat 页面管理

    <role rolename="admin-gui"/> <role rolename="manager-gui"/> <user ...

  3. java中List Set Map使用

    @Test         public void run()        {                              ArrayList<String> list= ...

  4. 二模11day1解题报告

    T1.树的重量(weight) 给出一棵n个叶节点的树(但是有多组数据)以及n个节点之间的距离(最短距离...然而也只有一条路),求树的所有边权之和. 一开始完全没有思路啊...难道爆搜模拟??狂汗. ...

  5. Windows phone 8 学习笔记(1) 触控输入(转)

    Windows phone 8 的应用 与一般的Pc应用在输入方式上最大的不同就是:Windows phone 8主要依靠触控操作.因此在输入方式上引入一套全新的触控操作方式,我们需要重新定义相关的事 ...

  6. select修改原生样式组件

    <div class="select"> <select class="" name=""> <option ...

  7. nice和taskset命令

    taskset -c 9,10 bash domain_analysis.sh && /home/work/odp/php/bin/php hourly_localdns_hijack ...

  8. nc命令学习

    监测端口是否存在 nc -z 127.0.0.1 9100 扫描端口 nc -z -v 127.0.0.1 8000 9999 发送http nc www.baidu.com 80 GET / HTT ...

  9. Oracle定时器执行多线程

    what里面加下面代码强制执行多线程   begin  execute immediate 'alter session force parallel dml parallel 16';  pkg_s ...

  10. C/C++下Netbeans的配置

    目录 目录1 1 netbeans开发环境搭建2 2 netbeans工程管理2 2.1 采用IDE自动生成Makefile2 3 netbeans工程配置2 3.1 编译工具链3 3.1.1 添加配 ...