美文网首页
iOS的NSString内存位置

iOS的NSString内存位置

作者: 加双芋 | 来源:发表于2018-10-10 14:21 被阅读58次

demo地址:https://github.com/Yueeeeee/YueTest
在iOS程序中声明NSString时,系统会根据使用方法,和声明的NSString的特性,把它声明到不同的内存位置,不管是声明到常量区的__NSCFConstantString类型还是NSTaggedPointerString,都是对字符串类型的一种内存优化,以下对NSString各个情况的内存位置进行了实验分析:

常量区

/**
 (lldb) p t1
 (__NSCFConstantString *) $0 = 0x000000010042b178 @"123"
 (lldb) p t11
 (__NSCFConstantString *) $0 = 0x0000000109133198 @"NSString存在几种形态NSString存在几种形态"
 (lldb) p t2
 (__NSCFConstantString *) $2 = 0x000000010042b178 @"123"
 (lldb) p t21
 (__NSCFConstantString *) $3 = 0x000000010042b198 @"NSString存在几种形态NSString存在几种形态"
 
 t1,t11,t2,t21四种初始化方式是完全一样的(initWithString:@"123"会报"a literal is redundant"警告,"文字是多余的")
 内存地址较低 : 0x000000010042b178
 初始化到"常量区"
 类型为"__NSCFConstantString",不会因为字符串的长短自动改变类型
 */
NSString *t1 = @"123";
NSString *t11 = @"NSString存在几种形态NSString存在几种形态";
NSString *t2 = [[NSString alloc] initWithString:@"123"];
NSString *t21 = [[NSString alloc] initWithString:@"NSString存在几种形态NSString存在几种形态"];

堆区(NSString)

/**
 (lldb) p t3
 (NSTaggedPointerString *) $4 = 0xc13ea6955a40bf35 @"123"
 (lldb) p t31
 (__NSCFString *) $5 = 0x0000600000e1a000 @"NSString存在几种形态NSString存在几种形态"
 (lldb) p t32
 (NSTaggedPointerString *) $0 = 0xcd050a5c49ea194e @"12345678"
 (lldb) p t33
 (NSTaggedPointerString *) $1 = 0xcce8bd53383670ff @"123456789"
 (lldb) p t34
 (__NSCFString *) $2 = 0x0000600000d08740 @"12345678999"
 (lldb) p t35
 (NSTaggedPointerString *) $3 = 0xcf1226008b44cb6d @"aaaaaaaaaaa"
 (lldb) p t36
 (__NSCFString *) $4 = 0x0000600000d08a60 @"存"
 
 用stringWithFormat方法初始化,分两种情况,系统会判断字符串内容所需的存储地址:
 不满足Tagged Pointer存储地址条件:t31
    地址较高 : 0x000060000152b930
    初始化到"堆区"
    类型"__NSCFString"
 
 满足Tagged Pointer存储地址条件:t3
    地址更高 : 0xc13ea6955a40bf35(不是一个真正的指针)
    初始化到"常量区"
    类型"NSTaggedPointerString"
    关于NSTaggedPointerString 参考http://www.infoq.com/cn/articles/deep-understanding-of-tagged-pointer/
    NSTaggedPointerString 的指针不是一个真的指针,而是苹果将值直接存储到了指针本身里面
    所以Tagged Pointer指针的值不再是地址了,而是真正的值,它的内存并不存储在堆中,也不需要malloc和free。
    我就暂且理解为他的内存分区在"常量区"
    Tagged Pointer专门用来存储小的对象,例如NSNumber和NSDate
    Tagged Pointer在内存读取上有着3倍的效率,创建时比以前快106倍。
*/
NSString *t3 = [NSString stringWithFormat:@"123"];
NSString *t31 = [NSString stringWithFormat:@"NSString存在几种形态NSString存在几种形态"];
NSString *t32 = [NSString stringWithFormat:@"12345678"];
NSString *t33 = [NSString stringWithFormat:@"123456789"];
NSString *t34 = [NSString stringWithFormat:@"12345678999"];
NSString *t35 = [NSString stringWithFormat:@"aaaaaaaaaaa"];
NSString *t36 = [NSString stringWithFormat:@"存"];

堆区(NSMutableString)

/**
 (lldb) p t5
 (__NSCFString *) $0 = 0x0000600003b82b50 @"123"
 (lldb) p t51
 (__NSCFString *) $1 = 0x0000600003b82940 @"NSString存在几种形态NSString存在几种形态"
 (lldb) p t6
 (NSTaggedPointerString *) $2 = 0xefb3efbe03764e44 @"123"
 (lldb) p t61
 (__NSCFString *) $3 = 0x00006000016f3d90 @"NSString存在几种形态NSString存在几种形态"
 
 t5,t51内存地址 : 0x0000600003b82b50
 初始化到"堆区"
 类型"__NSCFString"
 
 t6内存地址 : 0xefb3efbe03764e44
 初始化到"常量区"
 类型为"NSTaggedPointerString"
 
 t61内存地址 : 0x00006000016f3d90
 初始化到"堆区"
 类型为"__NSCFString"
 */
NSMutableString *t5 = [[NSMutableString alloc] initWithString:@"123"];
NSMutableString *t51 = [[NSMutableString alloc] initWithString:@"NSString存在几种形态NSString存在几种形态"];
NSString *t6 = [t5 copy];
NSString *t61 = [t51 copy];

相关文章

网友评论

      本文标题:iOS的NSString内存位置

      本文链接:https://www.haomeiwen.com/subject/ujmpaftx.html