多线程

来源:互联网 发布:tb软件 编辑:程序博客网 时间:2024/06/17 07:02

本篇博文是对iOS多线程中的一些细节的小点进行记录,而对iOS中3种多线程支持(NSThread,NSOperation和NSOperationQueue,GCD)的具体知识不做讲解。


1.当主线程结束时,其他线程不受任何影响,并不会随之结束。一旦子线程启动起来后,它就与主线程地位相同,不受影响。


2.iOS规定只能在主线程(UI线程)中修改UI控件的属性,即刷新UI。因此,可以在子线程中调用performSelectorOnMainThread:withObject:waitUntilDone: 方法刷新UI。

3.多线程中子线程的优先级默认是0.5,即thread.threadPriority = 0.5;
1.0的优先级更高,即会获得跟多的执行机会,而不是完全优先执行完毕。

4.@synchronized(obj){}实现同步,保证多线程安全。obj是同步监视器,任何时刻只能有一个线程可以获得对同步监视器的锁定,当同步代码块执行完毕后,该线程会自动释放对同步监视器的锁定(推荐使用可能被并发访问的共享资源充当同步监视器)。

线程安全是以降低程序的运行效率为代价的。
应对策略:(1)只对那些会改变竞争资源的方法进行同步。
(2)若有单线程和多线程两种运行环境,在单线程中就使用不安 全版本即可,多线程中需要使用安全版本。

5.同步锁(NSLock)
通常为全局变量 NSLock *lock;
lock = [ [NSLock alloc] init];
[lock lock];
// 需要保证线程安全的代码
[lock unlock];

6.NSCondition:使用lock方法进行资源的申请,使用unlock方法进行资源的释放,申请资源之后可以调用wait方法进行挂起状态,等待被唤醒,调用signal方法唤醒其他正在等待的线程(需抢占),调用broadcast唤醒其他所有等待的线程。使用NSCondition进行资源申请不能嵌套使用,即使在一个线程中也不能这样操作,否则会进行死锁状态。

7.GCD
GCD中多次执行的任务:dispatch_apply()函数将控制提交的代码块重复执行多次,如果该代码块被提交给并发队列,系统可以使用多线程并发执行同一个代码块
GCD中只执行一次的任务:dispatch_once()函数将控制提交的代码块在整个应用的生命周期内最多执行一次——只有在第一次提交该代码块时,该代码才会获得执行的机会。而且该函数无须传入队列,这意味着系统将直接用主线程执行该函数提交的代码块。()中的第一个参数为dispatch_once_t ,创建这个变量时必须在前面加上static:static dispatch_once_t onceToken;

8.定义NSOperation子类
NSOperation一般不会直接拿来使用,而是选择创建它的子类,需要重写- (void)main;方法,该方法的方法体将作为NSOperationQueue完成的任务。

9.后台运行相关
(1)当应用程序进入后台时,系统会自动回调应用程序委托的applicationDidEnterBackground:方法。在转入后台前要释放所有可以释放的内存,保存用户数据和状态信息。(应用暂停时占用的内存越少,iOS彻底终止该应用的风险就越小)
(2)使用默认的通知中心监听应用转入后台的过程,应用转入后台时会向通知中心发送UIApplicationDidEnterBackgroundNotification;使用默认的通知中心监听应用转入前台的过程,应用转入前台时会向通知中心发送UIApplicationWillEnterForegroundNotification。
(3)为了让应用不会丢失应用数据,应在应用转入后台时记录应用状态:[[NSUserDefaults standardUserDefaults] setObject: forKey:]。
(4)请求更多的后台时间
当应用转入后台,不要在主线程中执行超过5秒的任务,如果应用转入后台花费了太多时间(即applicationDidEnterBackground:方法的执行体花费了太多时间)应用可能从内存中被删除。

请求更多的后台时间方法:1.调用UIApplication实例对象的beginBackgroudTaskWithExpirationHandler:方法获取更多的后台运行时间,默认获得10分钟后台时间;2.调用dispatch_async()方法将指定代码块提交给后台执行;3.后台任务执行完成时,调用UIAppliction实例对象的endBackgroundTask:方法结束后台任务。


0 0
原创粉丝点击