1.探索
首先通过
po [NSRunloop currentRunloop]
在控制台可以看到以下打印信息,发现runloop与autoreleasepool有关系

auto.png
我们可以推测,在触发obsever监听的时候,会处理autoreleasepool
order表示runloop处理的优先级
我们通过activities = 0xa0,可以监听autoreleasepool的处理
2.监听autoreleasepool
 char autoreleaseActive = 0xa0;    CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), autoreleaseActive, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {        
        NSLog(@"_wrapRunLoopWithAutoreleasePoolHandler");
        
    });通过实践,在一次runloop的周期中大概会执行5次。
添加一个信号断点

屏幕快照 2018-05-09 上午11.30.32.png
发现在闲置状态(beforeWating)会不时进入这个断点
3.从runloop源码探究

auto2.png
虽然autoreleasepool的处理一直被触发,但是并没有唤醒休眠状态的runloop
4. autoreleasepool源码
提问:arc有必要使用autoreleasepool吗?
在mrc的时代,往往创建一个autoreleasepool对象
arc则使用
@ autoreleasepool
提问:arc下使用@ autoreleasepool 的意义?
首先执行下面两段代码作为对比
 for (int i = 0; i < 1024*1024*30; i++) {        @autoreleasepool {            
            NSString *str = [NSString stringWithFormat:@"0123456789"];
            
        };
    }for (int i = 0; i < 1024*1024*30; i++) {            
            NSString *str = [NSString stringWithFormat:@"0123456789"];
            
    }结论:
第一段代码在会对内存进行优化,释放速度快;
第二段代码造成内存大量堆积,释放缓慢
通过clang解读@autoreleasepool源码
 @autoreleasepool {            
            NSString *str = [NSString stringWithFormat:@"0123456789"];
            
        };约等于
创建了一个autorelease对象 push autorelease NSString *str = [NSString stringWithFormat:@"0123456789"]; 释放掉autorelease(pop ~) clang
但是从clang出的源码中我们看不出释放,是因为autorelease的释放使用c++中的析构