autoreleasePool自动释放池,ARC模式下,苹果会自动进行内存管理,不需要我们手动去管理内存。这对于苹果开发者来说,省去了很多事情,不用再每天为了内存管理浪费掉宝贵的开发时间。大家都知道,在我们开发的ARC项目中,苹果会在合适的地方添加autoreleasePool,从而retain或者release对象。那么,请问:autoreleasePool在什么时机创建,在什么时机去释放呢?回答:这事只有ARC知道,我们开发者不知道。这种答案是不是很low呢?接下来,根据Runloop的运行机制,解释一下autoreleasePool到底是什么时机创建和释放。
当程序运行时,会有多条线程去执行进程中的任务,每个线程对应一个Runloop,实现原理是创建一个全局字典,key是线程对象,value是Runloop对象,从而线程和Runloop会一一对应。
Runloop内部结构图:我的理解,Mode其实是对Runloop内部结构的分组,一个Runloop包括多个Mode,每个Mode里面又包括source(事件源),
Observe(监听),Timer(定时源)。
autoreleasePool创建与释放时机与Observer相关.Observer是runloop执行任务的回调。
typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
kCFRunLoopEntry = (1UL << 0), //当进入runloop循环的时候,会执行对应的回调
kCFRunLoopBeforeTimers = (1UL << 1),//当执行定时源事件之前,会执行对应的回调
kCFRunLoopBeforeSources = (1UL << 2),//当执行source事件之前,会执行对应的回调
kCFRunLoopBeforeWaiting = (1UL << 5),//当runloop睡眠之前,会执行对应的回调
kCFRunLoopAfterWaiting = (1UL << 6),//当runloop睡眠之后,会执行对应的回调
kCFRunLoopExit = (1UL << 7),//当退出runloop,会执行对应的回调事件
kCFRunLoopAllActivities = 0x0FFFFFFFU
};
那么,我们来看看Main Runloop是在什么时机来处理autoreleasePool的!
Main Runloop里面对于autorelease的处理回调,那么,我们接下来分析回调的地方:
1。activities其实就是事件执行的时机,这里的activity对应的是kCFRunLoopEntry。当开启或者唤醒runloop的时候,会创建一个autoreleasePool;
2.这里的activity 0xa0 = 1010 0000 kCFRunLoopBeforeWaiting | kCFRunLoopExit当runloop睡眠之前或者退出runloop的时候会释放autoreleasePool;
总结:根据Runloop的运行机制,解释一下autoreleasePool到底是什么时机创建和释放?
回答:当开启或者唤醒runloop的时候,会创建一个autoreleasePool;kCFRunLoopBeforeWaiting | kCFRunLoopExit当runloop睡眠之前或者退出runloop的时候会释放autoreleasePool;
这是我对Runloop与autoreleasePool联系的见解,其中有错误的地方或者大家不明白的地方,请评论中提出不足点,感谢大家支持。
-----------------以下和autoreleasePool没有关系---------
Runloop是如何实现睡眠和唤醒的呢?这就要从OSX和iOS操作系统来分析了,OSX和iOS操作系统分为两大部分,分别是应用层和内核层。应用层中的应用程序包括很多线程,每个线程会通过mach_msg向内核层发送消息,内核层会把消息添加到cpu处理的消息队列中,等待cpu处理。当线程发送mach_msg()消息时,是告诉cpu我没有任务要处理了,我要进行休眠了。这时,该线程就不会浪费cpu资源了。但是线程会告诉cpu,如果有任务需要我来处理的时候,cpu要给我发送消息,把我唤醒,然后我来处理任务。大家要知道,内核层包括cpu,硬盘,摄像头,鼠标键盘灯输入设备,所以当用户与界面交互的时候,交互事件是从内核向上抛给应用程序的,结构图如下: