前段时间看了同事的分享,于是把它记录下来
先看下这几个测试代码,关于 NSString:
NSString *a = @"abc";
NSString *b = [[NSString alloc] init];
NSString *c = [[NSString alloc] initWithString:@"abc"];
NSString *d = [[NSString alloc] initWithFormat:@"abc"];
NSString *e = [NSString stringWithFormat:@"abc"];
NSString *f = [NSString stringWithFormat:@"123456789"];
NSString *g = [NSString stringWithFormat:@"1234567890"];
执行后打印输出结果:
变量名=a,类型=__NSCFConstantString
变量名=b,类型=__NSCFConstantString
变量名=c,类型=__NSCFConstantString
变量名=d,类型=NSTaggedPointerString
变量名=e,类型=NSTaggedPointerString
变量名=f,类型=NSTaggedPointerString
变量名=g,类型=__NSCFString
可以看出 NSString 是有几种类型的:
-
__NSCFConstantString
文字常量区存放常量字符串,程序结束后由系统释放,也就是说指向常量表的指针不受引用计数管理。所以对于NSCFConstantString类型的变量,OC 的内存管理策略对其无效 -
NSTaggedPointerString
对于64位程序,为了节省内存和提高运行速度,苹果引入了 Tagged Point 技术。NSTaggedPointerString是对NSCFString优化后的存在,在运行时创建时对字符串的内容和长度做出判断,若字符串内容是由ASCII字符构成且长度较小(大概十个字符以内),这时候创建的字符串就是NSTaggedPointerString类型,字符串直接存储在指针里,引用计数同样为-1,不适用对象的内存管理策略 -
Tagged Pointer
它的指针的值不再是地址了,而是真正的值。所以,实际上它不再是一个对象了,它只是一个披着对象皮的普通变量而已。所以,它的内存并不存储在堆中,OC 对象的内存管理方式对其无效。 -
__NSCFString
表示这是一个对象类型的字符串,在运行时创建,存储在堆区,服从OC 的对象内存管理策略。
我们可以看下面这张图:
关于NSString是不是还有很多惊喜呢?欢迎补充