iOS开发线程和RunLoop

 

一般来讲,一个线程一次只能执行一个任务,执行完毕后线程就会退出,如果我们需要一个机制让线程能随时处理时间但并不退出,通常的代码逻辑是这样:

这就是 Event Loop框架。

runloop实际上就是一个管理其需要处理的事件和消息的对象,并提供了一个入口函数来执行上面Event loop的逻辑。线程执行了这个函数之后,就会一直处于这个函数内部“接受消息-》等待-》处理”的循环中,知道这个循环结束(例如传入quite消息),函数返回。

在OSX和iOS系统中,提供了两个这样的对象:NSRunLoop和CFRunLoopRef。

CFRunLoopRef是基于CoreFoundation框架内的,它提供了纯C函数的API,所有这些API都是线程安全的。

NSRunLoop是基于CFRunLoopRef的封装,提供面向对象的API,但是这些API不是线程安全的。

RunLoop和线程的关系:iOS开发中有两个线程对象-pthread_t和NSThread。pthread_tNSThread是一一对应的。比如你可以通过pthrea_main_thread_np()或者[NSThread currentThread]来获取当前线程。CFRunLoop是基于pthread来管理的。

苹果不允许直接创建RunLoop,但是提供了两个自动获取的函数:CFRunLoopGetMain()和CGRunLoopGetCurrent()。这两个函数的内部逻辑大概为:

线程和RunLoop之间是一一对应的,其关系是保存在一个全局的Dictionary里。线程刚创建时并没有RunLoop,如果你不主动获取,它一直都不会有。runloop的创建是发生在第一次获取的时候,销毁时在线程结束时。你只能在一个线程的内部获取其RunLoop(主线程除外)。

Event驱动  主体就是一个死循环,没事-休眠,有事-唤醒-执行  

runloop:用于结局

1、使程序一直运行并接受用户输入

2、决定程序在何时应该处理哪些Event

3、调用解耦(Message Queue)

4、节省cpu时间

 

setNeedsLayout/setNeedsDisplay主动跟跟新UI。

iOS程序入口在int main函数,main函数内部会rentun ,一旦return就会结束程序,所以内部有个mainrunloop一种在运行,不会造成return,很多crash都是因为runloop不执行了就return了造成程序无法执行下去。

如图,程序执行的时候不会执行nslog因为mainRunLoop在运行,不会ruturn一旦ruturn程序会退出。

  mainRunLoop在一直执行,随时唤醒处理事件,如果没有runloop就不能实现随时处理事件。

 

foundation中的NSRunLoop对象是通过Core Foundation框架的CFRunLoopRef封装而来,提供的api比较少。cfrunloopref用的比较多。 

子线程的runloop默认关闭,第一次获取的时候才创建,有时候用不到浪费资源。runloop有资源才不会销毁,没资源会自定销毁。

API里面NSTimer 是木有暂停继续的方法的,只有fire和invalidate,前者是开工的意思,后者是废掉的意思 

在这种场景:要获取事件(例如button按下之前需要处理,但是又不知道什么时候按下去),用runloop监听runloop的状态,唤醒了就说明按钮按下去了。

 

监听各个状态在某个状态中处理事件。

以下是个各种状态

performSelector:......也是source。

主线程的runloop默认开启,子线程的runloop默认不开启,所以timer在子线程中是不会执行的,需要手动开启runloop。手动开runloop需要runloop中添加资源,没有资源的runloop会自动关闭。

runloop应用:  runloop默认是不开启的,在线程中第一次获取的时候创建,run开启。

1、Timer

2、UIImageView滑动不加载,runloop DefaultMode才加载。

3、PerformSelect

4、常驻线程:让子线程常驻,需要让他的runloop运行起来,那么mode种需要有source,在里买呢添加一个NSPort就行。

  进程就是每个应用程序运行就会有一个进程,各应用间进程彼此独立,进程依靠线程执行任务,每个进程至少有一个线程,线程中任务的执行是串行的,如果要在1个线程中执行多个任务,那么只能一个一个地按顺序执行这些任务,也就是说,在同一时间内,1个线程只能执行1个任务。

  线程中执行任务只能串行,但是线程可以并发执行。 同一时间,CPU只能处理1条线程,只有1条线程在工作(执行),多线程并发(同时)执行,其实是CPU快速地在多条线程之间调度(切换),如果CPU调度线程的时间足够快,就造成了多线程并发执行的假象     

  思考:如果线程非常非常多,会发生什么情况?

  CPU会在N多线程之间调度,CPU会累死,消耗大量的CPU资源,每条线程被调度执行的频次会降低(线程的执行效率降低)。

 

多线程的优点

能适当提高程序的执行效率

能适当提高资源利用率(CPU、内存利用率)

 

多线程的缺点

开启线程需要占用一定的内存空间(默认情况下,主线程占用1M,子线程占用512KB),如果开启大量的线程,会占用大量的内存空间,降低程序的性能

线程越多,CPU在调度线程上的开销就越大

程序设计更加复杂:比如线程之间的通信、多线程的数据共享

5、自动释放池

 

posted @ 2016-11-30 23:07  yiki  阅读(3178)  评论(0编辑  收藏  举报