理解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在堆上分配内存的局部变量,作用域结束被自动回收,所以在
viewWillAppear
和viewDidAppear
的时候string2已不复存在。场景:3
下面着重说一下通过类方法
stringWithFormat
创建的对象。为了更直观,我们拿场景2做对比,通过设置观察点发现alloc创建的对象在
viewDidLoad
作用域结束的时候就被回收了,而此时AutoreleasePool并没有被pop。文章图片
屏幕快照 2018-05-10 上午11.32.24.png
再观察一下类方法创建的对象,
viewWillAppear
方法结束的时候执行了 AutoreleasePoolPage::pop(void*)
方法。文章图片
屏幕快照 2018-05-10 上午11.33.07.png
由此我们可以得出结论,通过类方法创建的对象生命周期延长了,直到自动释放池被pop的时候才被销毁。同时也再次证明sunnyxx大神的论断
viewDidLoad
和viewWillAppear
是在同一个runloop调用的。另外 无论使用alloc还是类方法创建的对象,当内容是数字、英文字母、字符等,只要字符串的长度小于等于9就会转成NSTaggedPointerString类型。长度大于9或者有中文在就会变成NSCFString类型。NSTaggedPointerString类型也不会释放,其实对于NSTaggedPointerString类型来说,它的内容就在本身的指针里,不存在释放的问题。
Autorelease原理 【理解Autorelease从NSString开始】sunnyxx大神的《黑幕背后的Autorelease》写的很清楚了,这里不再赘述,有兴趣的可以去拜读一下,写的相当棒。
推荐阅读
- Docker应用:容器间通信与Mariadb数据库主从复制
- 一个人的碎碎念
- 我从来不做坏事
- 深入理解Go之generate
- 考研英语阅读终极解决方案——阅读理解如何巧拿高分
- 由浅入深理解AOP
- 从蓦然回首到花开在眼前,都是为了更好的明天。
- 逻辑回归的理解与python示例
- 西湖游
- 改变自己,先从自我反思开始