iphone多线程的使用
- 格式:rtf
- 大小:20.56 KB
- 文档页数:6
iOS开发多线程在实际项⽬中的运⽤实际项⽬开发中为了能够给⽤户更好的体验,有些延时操作我们都会放在⼦线程中进⾏。
今天我们就来聊聊多线程在实际项⽬中的运⽤。
我们先来看看多线程的基础知识:1.多线程的原理:同⼀时间,CPU只能处理⼀条线程,也就是只有⼀条线程在⼯作。
所谓多线程并发(同时)执⾏,其实是CPU快速的在多线程之间调度(切换)。
如果CPU调度线程的时间⾜够快,就造成了多线程并发执⾏的假象。
2.在实际项⽬开发中并不是线程越多越好,如果开了⼤量的线程,会消耗⼤量的CPU资源,CPU会被累死,所以⼀般⼿机只开1~3个线程为宜,不超过5个。
3.多线程的优缺点:优点:1.能适当提⾼程序的执⾏效率2.能适当提⾼资源的利⽤率,这个利⽤率表现在(CPU,内存的利⽤率)缺点:1.开启线程需要占⽤⼀定的内存空间(默认情况下,主线程占⽤1M,⼦线程占⽤512KB,如果开启⼤量的线程,会占⽤⼤量的内存空间,降低程序的性能)2.线程越多,CPU在调度线程上的开销就越⼤3.程序设计就越复杂:⽐如线程之间的通信,多线程的数据共享,这些都需要程序的处理,增加了程序的复杂度。
4.在iOS开发中使⽤线程的注意事项:1.别将⽐较耗时的操作放在主线程中2.耗时操作会卡住主线程,严重影响UI的流畅度,给⽤户⼀种“卡”的坏体验好了,多线程在iOS中的开发概念性的东西就讲这么多,下⾯我们来模拟⼀种开发中的场景:我们在开发中经常会遇到,当你要缓存⼀组图⽚,但是这些图⽚必须要等到你缓冲好了后再来展现在UI上,可是我们缓存图⽚的时候⽤的是SDWebImage框架,缓存的操作是异步进⾏的,我们如何来做到等缓存好了再来执⾏以后的操作呢?下⾯讲个实现起来⾮常简单,⽅便的⽅法:我先来放上代码,后⾯进⾏讲解://1.添加⼀个组let group = dispatch_group_create()//缓存图⽚for url in picURLs! {//2.将当前的下载操作添加到组中dispatch_group_enter(group)SDWebImageManager.sharedManager().downloadImageWithURL(url, options: SDWebImageOptions.init(rawValue: 0), progress: nil, completed: { (_, _, _, _, _) in //3.离开当前组dispatch_group_leave(group)print("正在缓存中...")})}//通过闭包将数据传递给调⽤者(通知图⽚缓存完毕)dispatch_group_notify(group, dispatch_get_main_queue()) {print("缓存完毕!")finished()}从输出结果我们就可以看出来:我们做到了缓存完毕后再来执⾏以后的操作。
iOS多线程——Thread(Swift版)1. 概述线程是⾮常有⽤的,当执⾏⼀个⽐较耗时的操作,但是⼜不想影响到主线程的时候,这个时候就需要多线程了,从⽽提⾼应⽤程序的性能,增强⽤户体验。
本篇⽂章将讲述iOS多线程中的⼀种Thread,下⾯来具体看⼀下。
作为⼀个开发者,有⼀个学习的氛围跟⼀个交流圈⼦特别重要,这是⼀个我的iOS交流群:,不管你是⼩⽩还是⼤⽜欢迎⼊驻,分享BAT,阿⾥⾯试题、⾯试经验,讨论技术,⼤家⼀起交流学习成长!2. Thread的创建@available(iOS 2.0, *)public convenience init(target: Any, selector: Selector, object argument: Any?)@available(iOS 10.0, *)public convenience init(block: @escaping () -> Void)@available(iOS 10.0, *)open class func detachNewThread(_ block: @escaping () -> Void)open class func detachNewThreadSelector(_ selector: Selector, toTarget target: Any, with argument: Any?)上⾯的⽅法中,前两个是对象的初始化⽅法,返回⼀个Thread对象,⽽后两个则是类⽅法,直接开启了⼀个⼦线程。
下⾯看⼀组测试:func createThread() {let thread1 = Thread(target: self, selector: #selector(threadMethod1), object: nil)let thread2 = Thread {print("thread2 \(Thread.current)")}thread1.start()thread2.start()Thread.detachNewThreadSelector(#selector(threadMethod3), toTarget: self, with: nil)Thread.detachNewThread {print("thread4 \(Thread.current)")}}@objc func threadMethod1() {print("thread1 \(Thread.current)")}@objc func threadMethod3() {print("thread3 \(Thread.current)")}运⾏后得到:thread4 <NSThread: 0x600002284600>{number = 9, name = (null)}thread2 <NSThread: 0x600002284540>{number = 7, name = (null)}thread1 <NSThread: 0x600002284500>{number = 6, name = (null)}thread3 <NSThread: 0x600002284580>{number = 8, name = (null)}通过初始化对象得到的Thread对象,需要调⽤start()⽅法来开启⼦线程,即将该⼦线程设置为就绪的状态,等待CPU的调度。
多线程概念:进程:正在进行的程序被称为进程,负责程序运行的内存分配,每个进程都有自己的独立虚拟内存空间.⏹线程线程是进程中一个独立的执行路径(控制单元)一个进程中至少包含一条线程,即主线程可以将耗时的执行路径(如:网络请求)放在其他线程中执行创建线程的目的就是为了开启一条新的执行路径,运行指定的代码,与主线程中的代码实现同时运行iOS的三种多线程技术NSThread•使用NSThread对象建立一个线程非常方便•但是!要使用NSThread管理多个线程非常困难,不推荐使用•技巧!使用[NSThread currentThread]跟踪任务所在线程,适用于这三种技术•NSOperation/NSOperationQueue是使用GCD实现的一套Objective-C的API是面向对象的线程技术•提供了一些在GCD中不容易实现的特性,如:限制最大并发数量、操作之间的依赖关系⏹GCD —— Grand Central Dispatch(1)是基于C语言的底层API(1)用Block定义任务,使用起来非常灵活便捷(1)提供了更多的控制能力以及操作队列中所不能使用的底层函数⏹提示:iOS的开发者,需要了解三种多线程技术的基本使用,因为在实际开发中会根据实际情况选择不同的多线程技术串行队列:#pragma mark -串行队列同步任务和异步任务- (void) GcdTest{//串行队列按顺序执行队列中的任务//新建一个串行队列dispatch_queue_t queue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);//调用同步方法for (int i=0; i<10; i++) {dispatch_sync(queue, ^{NSLog(@"srialQueue--sync--%@----%d",[NSThread currentThread],i);//同步任务中包含同步会造成线程阻塞// dispatch_sync(queue, ^{// NSLog(@"srialQueue--sync111--%@",[NSThread currentThread]); //// });});}//调用异步方法for (int i = 0; i<10; i++) {dispatch_async(queue, ^{NSLog(@"srialQueue--async--%@---%d",[NSThread currentThread],i);});}}执行详解:总结:同步操作不会新建线程、操作顺序执行(没用!)同步任务中包含同步会造成线程阻塞异步操作会新建线程、操作顺序执行(非常有用!)场景:既不影响主线程,又需要顺序执行的操作!。
一、引言随着移动应用的普及,用户对于应用的要求也变得越来越高。
除了良好的用户界面和流畅的用户体验,后台任务与多线程处理在iOS 移动应用开发中也显得尤为重要。
本文将探讨iOS移动应用开发中的后台任务与多线程处理方法,为开发者提供一些参考和指导。
二、后台任务的重要性1. 提升用户体验在iOS应用中,后台任务可以使应用在后台运行,并实时向用户提供更新和提示。
例如,当用户离开应用之后,应用可以继续进行数据同步、消息推送等任务,保证用户及时获取最新信息,提升用户体验。
2. 优化资源利用合理利用后台任务可以有效地优化资源利用。
例如,在后台进行数据的预加载和缓存,可以减少应用切换时的加载时间,提高应用响应速度。
三、后台任务的实现方法1. Background FetchBackground Fetch是iOS提供的一种后台任务处理方法。
开发者可以在应用中注册Background Fetch任务,并在系统空闲时进行数据的获取与更新。
当应用进入后台运行时,系统会根据设置的时间间隔自动触发Background Fetch任务。
2. Remote Notifications通过远程通知,开发者可以实现在应用后台运行时向用户发送消息、提醒等操作。
当用户收到远程通知时,可以根据通知内容进行相应的处理。
例如,收到一条新的消息时,应用可以在后台触发处理逻辑,更新数据并显示通知,为用户提供良好的互动体验。
3. 后台上传下载某些应用需要在后台进行大量的文件上传或下载操作。
iOS提供了Background Transfer Service来实现这些后台任务。
开发者可以通过NSURLSession来实现文件的上传、下载,保证应用在后台状态下的数据传输。
四、多线程处理的方法1. Grand Central Dispatch(GCD)GCD是iOS开发中的一种多线程处理方法。
开发者可以利用GCD来实现任务的异步执行、并发执行等操作。
通过合理地使用GCD,可以提高应用的响应速度和性能。
iOS中的多线程编程与并发处理在移动应用开发领域,iOS操作系统一直被誉为最稳定和高效的操作系统之一。
尽管如此,随着移动设备的日益复杂和用户需求的增加,开发者们需要更高效的方式来处理并发任务,以提供更好的用户体验。
iOS中的多线程编程和并发处理是解决这个问题的关键。
一、线程和进程的基本概念在探讨iOS中的多线程编程之前,我们首先需要了解线程和进程的基本概念。
进程是一个执行中的程序,拥有独立的内存空间和资源。
而线程是在进程内部执行的一条独立的路径,可以利用进程的资源,并与其他线程共享内存空间。
在iOS中,每个应用程序都运行在独立的进程中,而每个进程又可以包含多个线程。
二、为什么需要多线程编程多线程编程可以带来很多好处。
首先,它可以提高应用程序的响应速度和性能。
通过将耗时的任务放在后台线程中进行处理,我们可以保持主线程的响应性,确保用户操作不会被阻塞。
其次,多线程编程可以提高程序的并发能力,同时处理多个任务。
最后,多线程编程可以充分利用多核处理器的优势,提高应用程序的运行效率。
三、iOS中的多线程编程方式在iOS中,我们可以使用多种方式来实现多线程编程,如使用NSThread、GCD(Grand Central Dispatch)和NSOperationQueue等。
以下是它们的简要介绍:1. NSThreadNSThread是iOS中最基本的多线程编程方式,它包装了一个线程对象,开发者可以直接创建和管理线程。
NSThread需要开发者手动管理线程的生命周期,包括线程的启动、暂停和销毁等。
由于需要手动管理,使用NSThread的复杂度相对较高。
2. GCD (Grand Central Dispatch)GCD是iOS中推荐使用的多线程编程方式之一。
它是一个用于并行执行任务的技术。
GCD将任务分成若干块,然后根据系统的资源状况智能地调度这些任务。
相比于NSThread,GCD提供了更高级、更简洁的API,大大降低了多线程编程的复杂度。
iOS开发入门之后终究是要接触多线程和runloop的,本片文章就简单讲下iOS 开发中的多线程技术。
线程、进程什么是线程、进程有的人说进程就像是人的脑袋,线程就是脑袋上的头发(谁这么说的?打死他!)。
其实这么比方不算错,但是更简单的来说,用迅雷下载文件,迅雷这个程序就是一个进程,下载的文件就是一个线程,同时下载三个文件就是多线程。
一个进程可以只包含一个线程去处理事务,也可以有多个线程。
多线程的优点和缺点多线程可以大大提高软件的执行效率和资源(CPU、内存)利用率,因为CPU 只可以处理一个线程(多核CPU另说),而多线程可以让CPU同时处理多个任务(其实CPU同一时间还是只处理一个线程,但是如果切换的够快,就可以了认为同时处理多个任务)。
但是多线程也有缺点:当线程过多,会消耗大量的CPU资源,而且,每开一条线程也是需要耗费资源的(iOS主线程占用1M内存空间,子线程占用512KB)。
iOS开发中的多线程iOS程序在启动后会自动开启一个线程,称为主线程或者UI线程,用来显示、刷新UI界面,处理点击、滚动等事件,所以耗费时间的事件(比如网络、磁盘操作)尽量不要放在主线程,否则会阻塞主线程造成界面卡顿。
iOS开发中的多线程实现方案有四种:技术方案简介语言生命周期管理技术方案 简介 语言 生命周期管理pthread 一套通用的多线程API ,适用于Unix\Linux\Windows 等系统,跨平台\可移植,使用难度大 C程序员管理NSThread 使用更加面向对象,简单易用,可直接操作线程对象 Objective-C 程序员手动实例化GCD 旨在替代NSThread 等线程技术,充分利用设备的多核 C自动管理 NSOperation 基于GCD (底层是GCD ),比GCD 多了一些更简单实用的功能,使用更加面向对象 Objective-C 自动管理多线程中GCD 我使用比较多,以GCD 为例,多线程有两个核心概念:1. 任务 (做什么?)2. 队列 (存放任务,怎么做?)任务就是你开辟多线程要来做什么?而每个线程都是要加到一个队列中去的,队列决定任务用什么方式来执行。
iOS中的多线程编程与并发处理在移动应用开发中,多线程编程和并发处理是非常重要的技术,尤其是在iOS平台,其用户体验的良好与否往往与应用的多线程处理能力密不可分。
本文将探讨iOS中的多线程编程与并发处理技术,并讨论其应用场景及最佳实践。
一、并发处理的重要性随着智能手机的普及,用户对于应用的实时响应能力和流畅性有着更高的要求。
而并发处理则是保证应用能够在处理多个任务时不打乱用户操作流程的关键。
通过合理的多线程设计,开发人员可以利用多核处理器的优势,将不同的任务分配到不同的线程上进行并行处理,从而提高应用的性能与响应速度。
二、多线程编程基础在iOS中,多线程编程主要依靠Grand Central Dispatch(GCD)和Operation Queue来实现。
GCD是一种基于队列的技术,通过将任务添加到不同的队列中,由系统自动管理线程的创建和销毁,从而实现并发处理。
而Operation Queue则是对GCD的更高级封装,提供了更多的功能和灵活性。
三、并发处理的应用场景1. 后台下载与上传:在许多应用中,需要进行大文件的下载和上传操作,而这些操作往往会占用较长的时间。
为了不阻塞主线程,可以将这些操作放到后台线程进行处理,同时提供进度展示和取消功能,提高用户体验。
2. 图像处理:图像处理是许多应用中常见的需求,然而一些高级处理算法可能耗时较长。
通过在后台线程进行图像处理,并在主线程中更新UI,可以保持应用的流畅性。
3. 数据库操作:数据库的读写操作也是需要注意的并发处理场景。
通过将读操作放到后台线程进行,可以保证主线程的响应性,同时在数据写操作时进行同步处理,避免数据冲突。
四、多线程编程的最佳实践1. 避免主线程阻塞:主线程是UI显示和用户交互的线程,如果在该线程中执行耗时操作,会导致应用无法响应用户操作。
因此,应该将耗时操作放到后台线程中进行。
2. 合理管理线程数:创建过多的线程会导致系统资源过度占用,甚至引发线程爆炸。
iOS中的多线程编程与并发处理在当今移动应用开发的领域,iOS平台的应用程序已经成为主流。
为了提高应用程序的性能和用户体验,多线程编程与并发处理成为了iOS开发者需要掌握的重要技能。
本文将深入讨论iOS中的多线程编程与并发处理,并探讨如何在应用中有效地利用这些技术。
1. GCD简介与使用Grand Central Dispatch(GCD)是iOS平台多线程编程的基础,它提供了一种简单而强大的方式来进行并发处理。
通过GCD,我们可以将任务分发到并发队列中,由系统在不同的线程上执行。
此外,GCD还可以管理线程池、线程间通信以及避免资源竞争等问题。
为了使用GCD,我们首先需要创建一个队列。
队列可以分为串行队列和并发队列两种类型。
串行队列按照添加顺序执行任务,而并发队列则可以同时执行多个任务。
通过使用合适的队列类型,我们可以根据具体需求来进行任务调度。
在代码实现方面,创建队列可以使用`dispatch_queue_create`函数,执行任务可以使用`dispatch_async`或`dispatch_sync`函数。
通过调用`dispatch_get_main_queue`函数,我们可以获取主队列,用于在主线程上执行UI相关的任务。
2. GCD中的任务执行方式在GCD中,任务可以以不同的方式进行执行。
我们常见的有`dispatch_async`、`dispatch_sync`以及`dispatch_after`等函数。
- `dispatch_async`函数用于异步执行任务,即将任务添加到队列中后,不阻塞当前线程继续执行下一行代码。
- `dispatch_sync`函数用于同步执行任务,即将任务添加到队列中后,当前线程会被阻塞直到任务执行完成。
- `dispatch_after`函数用于延迟执行任务,在指定的时间后将任务添加到队列中。
除了这些基本的任务执行方式外,GCD还提供了其他更为复杂的执行方式,如`dispatch_barrier_async`(用于创建读写锁)、`dispatch_apply`(用于执行指定次数的任务)等。
Apple's OpenCL——多线程同步时间: 2010-11-10 17:04点击:1386 次OpenCL 即:Open Computing Language,是由苹果公司起草设计的用于大规模并行计算的计算编程语言。
CocoaChina 版主 zenny_chen 今天为我们带来新的一篇 OpenCL 教程:多线程同步。
(附:点击这里OpenCL 即:Open Computing Language,是由苹果公司起草设计的用于大规模并行计算的计算编程语言。
CocoaChi na 版主“zenny_chen” 今天为我们带来新的一篇 OpenCL 教程:多线程同步。
(附:点击这里查看 zenny_chen 版主的所有教程帖)我们前几章介绍了OpenCL的一些基本概念以及一些基本的用法。
我们之前的例子都是线程独立计算的,相互之间没有任何通信。
而这样的计算模型也是GPU最最喜欢的,能完全发挥GPU众核并行计算的优势。
今天我们将介绍OpenCL多线程同步技巧。
我们下面的例子将是以一个简单的求和算法来描述如何同步一个工作组内的线程以及工作组之间如何同步。
我们之前介绍过变量的地址属性。
用__global修饰的变量存放在显示存储器中,特点是容量很大,但访问速度很慢,并且所有工作项都能访问;而用 __local修饰的变量存放在共享存储器,其特点是速度比全局存储要快很多,并且在同一工作组内的工作项能够对其进行访问,而且每个工作组有自己独立的共享存储器;__private修饰或默认状态下定义的变量是私有的,即存放在寄存器中,其特点是访问速度相当快,基本上一次读或写仅需要1个着色器周期,但它是工作项私有的,并且每个工作项只有若干个寄存器可以进行访问。
如果我们让在一个工作组内的线程进行同步,那么我们可以借助共享存储变量来帮我们达成这个目标;而如果是工作组之间的通信,则需要全局存储变量。
下面看求和的内核代码:__kernel void solve_sum(__global int input[4096],__global int output[9]){__local int localBuffer[512];size_t item_id = get_local_id(0);size_t gid = get_global_id(0);localBuffer[item_id] = input[gid];barrier(CLK_LOCAL_MEM_FENCE);if((item_id) == 0){int s = 0;for(int i = 0; i < 512; i++)s += localBuffer;output[get_group_id(0)] = s;output[8] = get_num_groups(0);}}在以上代码中,一共有4096个工作项,共有8个工作组,这样每个工作组就有512个工作项。
iOS移动应用开发技术中的后台任务与多线程处理方法在当今移动应用开发领域中,后台任务和多线程处理技术是至关重要的。
它们可以帮助开发者优化应用的性能和用户体验,提高应用的稳定性和响应速度。
本文将探讨iOS移动应用开发中的后台任务和多线程处理方法,并介绍一些常用的技术和思路。
一、后台任务的重要性随着移动设备的日益普及和功能的日益强大,用户对移动应用的需求也越来越高。
然而,移动设备的资源是有限的,对于一些耗时的任务,如果放在前台处理,可能会影响用户的操作体验。
因此,将一些无需用户实时参与的任务放在后台进行处理,成为了改善用户体验的重要手段。
二、后台任务的实现原理在iOS中,后台任务的实现通常由两部分组成:后台运行模式和后台任务执行机制。
后台运行模式指的是应用在后台进行任务处理的能力,而后台任务执行机制则负责具体的任务调度和执行。
1. 后台运行模式iOS中的后台运行模式包括:音频播放、位置更新、远程通知等。
开发者可以根据应用的需求选择合适的后台运行模式,并在应用的文件中进行配置。
比如,如果开发的是一个音乐播放器应用,可以选择音频播放模式,以确保播放器在后台一直运行。
2. 后台任务执行机制在iOS中,后台任务的执行主要通过两种方式实现:后台任务和多线程处理。
后台任务是指在App Delegate的方法中调用beginBackgroundTaskWithName:expirationHandler:方法来开启一个后台任务,用于在应用进入后台后继续执行一些任务。
而多线程处理是指将一些耗时的任务放在其他线程中进行处理,以充分利用设备的多核处理能力。
三、多线程处理的方法和技术多线程处理是iOS移动应用开发中常用的技术之一,它可以帮助开发者充分利用设备的多核处理能力,提高应用的性能和响应速度。
下面介绍几种常用的多线程处理方法和技术。
1. GCD(Grand Central Dispatch)GCD是苹果提供的一套并发处理机制,它基于队列模型,将任务放在队列中按照先进先出的原则进行执行。
iphone多线程的使用热度8已有1677 次阅读2010-8-5 16:23 |以下是开发初期收集整理的一点资料,简单实用,希望对新人有帮助,都是网络上收集的,原始出处以不明,若侵犯您的权益,请告知,本人将及时删除相关内容。
多线程之NSInvocationOperation 多线程编程是防止主线程堵塞,增加运行效率等等的最佳方法。
而原始的多线程方法存在很多的毛病,包括线程锁死等。
在Cocoa中,Apple提供了NSOperation这个类,提供了一个优秀的多线程编程方法。
本次介绍NSOperation的子集,简易方法的NSInvocationOperation: @implementation MyCustomClass - (void)launchTaskWithData:(id)data { //创建一个NSInvocationOperation对象,并初始化到方法 //在这里,selector 参数后的值是你想在另外一个线程中运行的方法(函数,Method) //在这里,object后的值是想传递给前面方法的数据 NSInvocationOperation* theOp = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(myTaskMethod:)object:data]; // 下面将我们建立的操作“Operation”加入到本地程序的共享队列中(加入后方法就会立刻被执行) // 更多的时候是由我们自己建立“操作”队列 [[MyAppDelegate sharedOperationQueue] addOperation:theOp]; } // 这个是真正运行在另外一个线程的“方法” - (void)myTaskMethod:(id)data { // Perform the task. } @end一个NSOperationQueue 操作队列,就相当于一个线程管理器,而非一个线程。
因为你可以设置这个线程管理器内可以并行运行的的线程数量等等。
下面是建立并初始化一个操作队列:@interface MyViewController : UIViewController{ NSOperationQueue *operationQueue; //在头文件中声明该队列 } @end @implementation MyViewController - (id)init { self = [super init]; if (self){ operationQueue = [[NSOperationQueue alloc] init]; //初始化操作队列 [operationQueue setMaxConcurrentOperationCount:1]; //在这里限定了该队列只同时运行一个线程 //这个队列已经可以使用了 } return self; } - (void)dealloc { [operationQueue release]; //正如Alan经常说的,我们是程序的好公民,需要释放内存! [super dealloc]; } @end简单介绍之后,其实可以发现这种方法是非常简单的。
很多的时候我们使用多线程仅仅是为了防止主线程堵塞,而NSInvocationOperation就是最简单的多线程编程,在iPhone 编程中是经常被用到的。
////////////////////////////////////////////////////////////////////// ///////////////////////////// 1 在主线程里加入一个loading画面…… 2 { 3 [window addSubview:view_loading]; 4 [NSThread detachNewThreadSelector:@selector(init_backup:)toTarget:self withObject:nil]; 5 } 可以通过performSelectorOhMainThread更新UI元素,比如设置进度条等等。
最后消除loading画面,载入主View。
7 -(void)init_backup:(id)sender 8 { 9 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 10 11 // ... 12 int i = status; 13 [selfperformSelectorOnMainThread:@selector(show_loading:) withObject:[NSNumber numberWithInt:i] waitUntil Done:NO]; 14 15 [view_loading removeFromSuperview]; 16 [window addSubview:tabcontroller_main.view]; 17 [pool release]; 18 }///////////////////////////////////////////////////////利用iphone的多线程实现和线程同步 从接口的定义中可以知道,NSThread和大多数iphone的接口对象一样,有两种方式可以初始化:一种使用initWithTarget :(id)target selector:(SEL)selector object:(id)argument,但需要负责在对象的retain count为0时调用对象的release方法清理对象。
另一种则使用所谓的convenient method,这个方便接口就是detachNewThreadSelector,这个方法可以直接生成一个线程并启动它,而且无需为线程的清理负责。
#import <UIKit/UIKit.h> @interface SellTicketsAppDelegate : NSObject <UIApplicationDelegate> { int tickets; int count; NSThread* ticketsThreadone; NSThread* ticketsThreadtwo; NSCondition* ticketsCondition; UIWindow *window; }@property (nonatomic, retain) IBOutlet UIWindow *window; @end然后在实现中添加如下代码: // SellTicketsAppDelegate.m // SellTickets // // Created by sun dfsun2009 on 09-11-10. // Copyright __MyCompanyName__ 2009. All rights reserved. // #import "SellTicketsAppDelegate.h" @implementation SellTicketsAppDelegate @synthesize window; - (void)applicationDidFinishLaunching:(UIApplication *)application { tickets = 100; count = 0; // 锁对象 ticketCondition = [[NSCondition alloc] init]; ticketsThreadone = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil]; [ticketsThreadone setName:@"Thread-1"]; [ticketsThreadone start]; ticketsThreadtwo = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil]; [ticketsThreadtwo setName:@"Thread-2"]; [ticketsThreadtwo start]; //[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil]; // Override point for customization after application launch [window makeKeyAndVisible]; } - (void)run{ while (TRUE){ // 上锁 [ticketsCondition lock]; if(tickets > 0) { [NSThreadsleepForTimeInterval:0.5]; count = 100 - tickets; NSLog(@"当前票数是:%d,售出:%d,线程名:%@",tickets,count,[[NSThread currentThread] name]); tickets--; }else { break; } [ticketsCondition unlock]; } } - (void)dealloc { [ticketsThreadone release]; [ticketsThreadtwo release]; [ticketsCondition release]; [window release]; [super dealloc]; } @end------------------------------------------------------------------------------------- // 定义 #import <UIKit/UIKit.h>@interface ThreadSyncSampleViewController : UIViewController { int _threadCount; NSCondition*_myCondition; }@end//实现文件如下:#import "ThreadSyncSampleViewController.h"@implementation ThreadSyncSampleViewController/* // The designated initializer. Override to perform setup that is required before the view is loaded. -(id)initWithNibName:(NSString *)nibNameOrNilbundle:(NSBundle *)nibBundleOrNil { if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]){ // Custom initialization } return self; } */ /* // Implement loadView to create a view hierarchy programmatically, without using a nib. - (void)loadView { } */// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. - (void)viewDidLoad{ [super viewDidLoad]; // //_myCondition = nil; // _myCondition = [[NSCondition alloc] init]; // NSTimer*timer = [NSTimer scheduledTimerWithTimeInterval:30 target:self selector:@selector(threadTester) userInfo:nil repeats:YES]; [timer fire]; } - (void)threadTester{ [_myCondition lock]; _threadCount = -2; //如果有n个要等待的thread,这里置成-n [_myCondition unlock]; // NSLog(@""); NSLog(@"------------------------------------------------------------------------------"); [NSThread detachNewThreadSelector:@selector(threadOne) toTarget:self withObject:nil]; [NSThread detachNewThreadSelector:@selector(threadTwo) toTarget:self withObject:nil]; [NSThread detachNewThreadSelector:@selector(threadThree) toTarget:self withObject:nil]; return; }- (void)threadOne{ NSLog(@"@@@ In thread 111111 start."); [_myCondition lock]; int n = rand()%5 + 1; NSLog(@"@@@ Thread 111111 Will sleep %d seconds ,now _threadCount is : %d",n,_threadCount); sleep(n); //[NSThread sleepForTimeInterval:n]; _threadCount ++ ; NSLog(@"@@@ Thread 111111 has sleep %d seconds ,now _threadCount is : %d",n,_threadCount); [_myCondition signal]; NSLog(@"@@@ Thread 1111111 has signaled ,now _threadCount is : %d",_threadCount); [_myCondition unlock]; NSLog(@"@@@ In thread one complete."); [NSThread exit]; return; }- (void)threadTwo{ NSLog(@"### In thread 2222222 start."); [_myCondition lock]; int n = rand()%5 + 1; NSLog(@"### Thread 2222222 Will sleep %d seconds ,now _threadCount is : %d",n,_threadCount); sleep(n); // [NSThread sleepForTimeInterval:n]; _threadCount++ ; NSLog(@"### Thread 2222222 has sleep %d seconds ,now _threadCount is : %d",n,_threadCount); [_myCondition signal]; NSLog(@"### Thread 2222222 has signaled ,now _threadCount is : %d",_threadCount); [_myCondition unlock]; //_threadCount ++ ; NSLog(@"### In thread 2222222 complete."); [NSThread exit]; return; }- (void)threadThree{ NSLog(@"<<< In thread 333333 start."); [_myCondition lock]; while (_threadCount < 0) { [_myCondition wait]; } NSLog(@"<<< In thread 333333 ,_threadCount now is %d ,will startwork.",_threadCount); [_myCondition unlock]; NSLog(@"<<< In thread 333333 complete."); [NSThread exit]; return; }/* // Override to allow orientations other than the default portrait orientation. -(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOri entation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation == UIInterfaceOrientationPortrait); } */- (void)didReceiveMemoryWarning { // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; // Release any cached data, images, etc that aren't in use. }- (void)viewDidUnload { // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; } - (void)dealloc { [_myCondition release]; [super dealloc]; }@end/?fromuid=39833。