线程的可选方案objective-c
有时候,你不想继承threads或不想本身建立和管理单独的线程。例如,你想要一个定时器每2秒钟调用你的方法,你可能会写一个线程一直循环,而后睡眠2秒,而后调用你的方法。或者你可能想要写代码处理异步请求,好比从网络上下载文件。或者当你的iPhone空闲时,你想要继续进行重量级的计算处理。这些都不太容易实现或者可能会下降性能。我会讨论一些解决的办法。安全
NSTimer服务器
NSTimer并不承诺会很精确;若是你设置每0.5秒触发一次,实际上定时器触发的时间可能在0.55和0.6秒之间。可是,若是你只是想相对准确的执行周期性任务的话,这是一个很好的机制。网络
重复和非重复NSTimer比较多线程
你能够执行重复或非重复的定时器。对于重复的定时器来讲,定时器会在你指定的时间间隔内触发,不会中止。若是你想中止的话,你须要手工的使定时器无效。对于非重复定时器来讲,它只会触发一次,而后会自动的变为无效。对这两种状况,一旦定时器无效了,你不能在重用它;你必须从新建立一个定时器对象。异步
要建立一个定时器,你可使用:ide
+ scheduledTimerWithTimeInterval:target:selector:userInfo: repeats: 函数
或使用:oop
+ timerWithTimeInterval:target:selector:userInfo:repeats: post
第一种方法会建立一个新的定时器,而后添加到当前的run loop中,而后返回定时器对象给你。第二种方法仅仅建立一个定时器对象;你须要本身经过调用[aTimer addTimer: forMethod]来添加到你本身的run loop中。
当时候重复定时器时,若是你要使定时器变成无效的话,你须要调用方法:[aTimer invalidate];
注意:在一个没有run loop的线程中,NSTimer是不能工做的。 |
异步函数
在不少状况下,异步函数比线程更轻量级。例如,iPhone环境可以从线程池中重用线程来处理异步函数。更进一步,若是你须要处理100个异步函数,OS可能只须要10个线程,由于一个线程可以处理多个异步函数。惟一的问题就是,它比你建立一些线程和一个异步请求来处理他们看起来更复杂。
Listing 6-9 代码块建立了一个异步请求到服务器上,而后合并返回的结果建立一个数据对象。
相比,使用简单的线程和异步函数处理方案:
@autoreleasepool {
NSData *p_w_picpathData = [NSData dataWithContentsOfURL:p_w_picpathURL];
}
在某些状况下,你可能须要写更多的代码来得到更好的性能。你仅仅须要确保实际上作的什么将对你有利。
若是你使用异步HTTP请求,你须要运行在一个后台线程中。若是很长一段时间都没有响应,iOS的策略可能会杀掉你的应用。这会使得你的应用给别人一个很差的印象。
注意:若是你同时有不少HTTP调用,你应该考虑建立一个单独的线程来处理异步调用,从而避免在主线程上调用冲突。 |
Idle-Time Notifications 空闲通知
有些事情你只想在系统空闲的时候作。例如,你想要从iPhone发送反馈到服务器上,而你又不想在其余处理正在进行或其余用户正在和设备交互的时候发送。你只想在用户或设备没事可作的时候发送。若是是你本身的话,这确实是一个很难的事情。不太高兴的是,苹果已经提供了一个函数来处理了。你能够经过NSNotificationQueue 使用 NSPostWhenIdle类型 来post一个通知,像下面的代码:
你能够看到,它就像使用NSNotificationCenter那样来使用;你添加一个对象和方法做为观察者和selector。而后你能够post一个新的通知到队列中,这样方法就会在系统空闲的时候进行处理。
iPhone线程测试
线程的测试在第二章已经讨论过了,因此图6-13只是一个简单的温习。
这个测试并无提供太多的信息,除了应用中当前线程的状态。这个可以帮助你了解系统是否由于使用太多线程致使负荷太重,或线程挂起和等待太长时间,这是死锁的一个征兆。
总结
在本章,你学到了如何使用多线程来提高你应用的性能。概念其实是很是简单的:你建立一个新的线程来处理一些计算。可是,为了使得你的应用正确和安全的运行,你须要注意不少细节。你一样须要知道cpu密集型任务和IO密集型任务,来确保什么会致使性能提高,或使得性能降低。你学到了如何用不一样的方法建立,管理,运行线程。你一样学到了使用锁的objective-c风格和它的语法,线程同步的问题,这个其实是很是重要的。