理解Autorelease从NSString开始

2018年5月10日
前言 首先声明本文涉及到的内容并非本人原创,只是笔者在工作中遇到相关问题,通过查阅前人的成果,自己做的一些总结,初衷是加深印象,也方便自己以后查阅,如果能对读者有所帮助,那是鄙人的荣幸。
从NSString说起

#define Log(_var) ({ NSString *name = @#_var; NSLog(@"%@: %@ -> %p : %@", name, [_var class], _var, _var); }) __weak NSString *weak_string = nil; - (void)viewDidLoad { [super viewDidLoad]; // 场景:1 NSString *string1 = @"常量"; weak_string = string1; /* // 场景:2 NSString *string2 = [[NSString alloc] initWithFormat:@"实例方法"]; weak_string = string2; *//* // 场景:3 NSString *string3 = [NSString stringWithFormat:@"类方法"]; weak_string = string3; */ }- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; NSLog(@"%s", __func__); Log(weak_string); }- (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; NSLog(@"%s", __func__); Log(weak_string); }

输出
-[ViewController viewWillAppear:] weak_string: __NSCFConstantString -> 0x10cb408e0 : 常量 -[ViewController viewDidAppear:] weak_string: __NSCFConstantString -> 0x10cb408e0 : 常量

-[ViewController viewWillAppear:] weak_string: (null) -> 0x0 : (null) -[ViewController viewDidAppear:] weak_string: (null) -> 0x0 : (null)

-[ViewController viewWillAppear:] weak_string: __NSCFString -> 0x60c00002ece0 : 类方法 -[ViewController viewDidAppear:] weak_string: (null) -> 0x0 : (null)

场景:1
第一种情况没的说,string1的class是__NSCFConstantString,编译期创建,放在常量区,程序销毁的时候才被释放。
场景:2
第二种情况也很好理解,通过alloc在堆上分配内存的局部变量,作用域结束被自动回收,所以在viewWillAppearviewDidAppear的时候string2已不复存在。
场景:3
下面着重说一下通过类方法stringWithFormat创建的对象。
为了更直观,我们拿场景2做对比,通过设置观察点发现alloc创建的对象在viewDidLoad作用域结束的时候就被回收了,而此时AutoreleasePool并没有被pop。

理解Autorelease从NSString开始
文章图片
屏幕快照 2018-05-10 上午11.32.24.png
再观察一下类方法创建的对象,viewWillAppear方法结束的时候执行了 AutoreleasePoolPage::pop(void*)方法。

理解Autorelease从NSString开始
文章图片
屏幕快照 2018-05-10 上午11.33.07.png
由此我们可以得出结论,通过类方法创建的对象生命周期延长了,直到自动释放池被pop的时候才被销毁。同时也再次证明sunnyxx大神的论断viewDidLoadviewWillAppear是在同一个runloop调用的。
另外 无论使用alloc还是类方法创建的对象,当内容是数字、英文字母、字符等,只要字符串的长度小于等于9就会转成NSTaggedPointerString类型。长度大于9或者有中文在就会变成NSCFString类型。NSTaggedPointerString类型也不会释放,其实对于NSTaggedPointerString类型来说,它的内容就在本身的指针里,不存在释放的问题。
Autorelease原理 【理解Autorelease从NSString开始】sunnyxx大神的《黑幕背后的Autorelease》写的很清楚了,这里不再赘述,有兴趣的可以去拜读一下,写的相当棒。

    推荐阅读