ARC下自动释放池

ARC下,初始化对象,如果不是alloc/new/copy/mutablecopy的方法,系统都会对对象进行处理,加入自动释放池,延迟释放时机。

新建一个MacOS command line的项目

extern uintptr_t _objc_rootRetainCount(id obj);
extern void _objc_autoreleasePoolPrint(void);

int main(int argc, const char * argv[]) {
    NSMutableArray *arr01 = [NSMutableArray array];
    NSLog(@"%p", arr01);
    _objc_autoreleasePoolPrint();
    return 0;
}

结果打印自动释放池内容,可以看到arr01是被添加到自动呢释放池中。

2020-04-27 13:45:39.253262+0800 AutoReleaseCMD[2977:131172] 0x10045dc80
objc[2977]: ##############
objc[2977]: AUTORELEASE POOLS for thread 0x1000d2dc0
objc[2977]: 1 releases pending.
objc[2977]: [0x10080b000]  ................  PAGE  (hot) (cold)
objc[2977]: [0x10080b038]       0x10045dc80  __NSArrayM
objc[2977]: ##############
Program ended with exit code: 0

但是同样的代码,放到iOS项目viewDidLoad等方法中的结果却是,自动释放池中不存在该对象,按道理如果加入自动释放池,是不可能马上释放的。唯一的解释是为加入自动释放池。此处保留疑问。

NSMutableArray *arr01 = [NSMutableArray array];
NSLog(@"%p", arr01);
_objc_autoreleasePoolPrint();

而对比两种项目,不同之处在于一个运行与Runloop中,一个没有。于是将command的代码改动,让对象的初始化发生在runloop中。

extern uintptr_t _objc_rootRetainCount(id obj);
extern void _objc_autoreleasePoolPrint(void);

int main(int argc, const char * argv[]) {
    NSLog(@"1");
    [[NSRunLoop currentRunLoop] performBlock:^{
        NSMutableArray *arr01 = [NSMutableArray array];
        NSLog(@"%p", arr01);
        _objc_autoreleasePoolPrint();
    }];
    [[NSRunLoop currentRunLoop] runUntilDate:[[NSDate date] dateByAddingTimeInterval:1000]];
    NSLog(@"2");
    return 0;
}

运行发现,对象竟然不在自动释放池中。

2020-04-27 13:53:16.209729+0800 AutoReleaseCMD[3005:134437] 1
2020-04-27 13:53:16.210792+0800 AutoReleaseCMD[3005:134437] 0x10042dfb0
objc[3005]: ##############
objc[3005]: AUTORELEASE POOLS for thread 0x1000d3dc0
objc[3005]: 2 releases pending.
objc[3005]: [0x100810000]  ................  PAGE  (hot) (cold)
objc[3005]: [0x100810038]       0x10042bf90  __NSSingleObjectArrayI
objc[3005]: [0x100810040]  ################  POOL 0x100810040
objc[3005]: ##############
objc_autoreleaseReturnValue
objc_unsafeClaimAutoreleasedReturnValue
objc_retainAutoreleasedReturnValue

三个方法的处理并不只是简单的放到自动释放池那么简单

你可能感兴趣的:(ARC下自动释放池)