*NSString 内存存储解析

1 前言:

字符串是存在字符串常量池里面,然后要是有个指针想要指向一个字符串,先会到字符串常量区进行查找

  1. 如果没有,就在字符串的常量区创建一个,把指针指向字符串常量区
  2. 如果有,就直接把指针指向字符串的常量区。
    所以,相同内容的字符串指针,其指向的内存地址都是一样的, 但是这个些字符串的指针变量的内存地址则可以是不同的。

2 验证:

1. 代码:

@interface ViewController ()
@property (nonatomic,copy) NSString *heap_a;///堆区的a
@property (nonatomic,copy) NSString *heap_b;///堆区的b
@end
- (void)viewDidLoad {
    [super viewDidLoad];
    [self setUP];
}

- (void)setUP {
     NSLog(@"---------- 栈区的字符串 ------");
    NSString *a = @"a";
    NSString *b = @"a";
    
    NSLog(@"a对应的字符串对应的字符常量区地址= %p",a);
    NSLog(@"b对应的字符串对应的字符常量区地址= %p",b);
    
    NSLog(@"&a= %p",&a);
    NSLog(@"&b= %p",&b);
    
    NSLog(@".");
    NSLog(@"---------- 堆区的字符串 ------");
    self.heap_a = @"a";
    self.heap_b = @"a";
    
    NSLog(@"self.heap_a对应的字符串对应的字符常量区地址= %p",self.heap_a);
    NSLog(@"self.heap_b对应的字符串对应的字符常量区地址= %p",self.heap_b);
    
    NSLog(@"&a= %p",&_heap_a);
    NSLog(@"&b= %p",&_heap_b);
    
    NSLog(@".");
    NSLog(@"---------- 常量区的字符串 ------");
    NSLog(@"static_a对应的字符串对应的字符常量区地址= %p",static_a);
    NSLog(@"static_b对应的字符串对应的字符常量区地址= %p",static_b);
    
    NSLog(@"&static_a= %p",&static_a);
    NSLog(@"&static_b= %p",&static_b);
}

2.打印:

---------- 栈区的字符串 ------
a对应的字符串对应的字符常量区地址= 0x1071f9260
b对应的字符串对应的字符常量区地址= 0x1071f9260
&a= 0x7fff58a119b8
&b= 0x7fff58a119b0
.
---------- 堆区的字符串 ------
self.heap_a对应的字符串对应的字符常量区地址= 0x1071f9260
self.heap_b对应的字符串对应的字符常量区地址= 0x1071f9260
&a= 0x7fd6cc6053a0
&b= 0x7fd6cc6053a8
.
---------- 常量区的字符串 ------
static_a对应的字符串对应的字符常量区地址= 0x1071f9260
static_b对应的字符串对应的字符常量区地址= 0x1071f9260
&static_a= 0x1071fce40
&static_b= 0x1071fce48

3 总结:

  1. 字符串指针指向的地址都在字符串常量区:

从上面打印可以看出所有的指针指向的地址:都在0x1071f9260

  1. 栈区 / 常量区 / (属性)堆区 字符串指针的地址:
  1. 指针指向的地址是不一样的,证明每个内存地址都开辟了一个指针空间,但是存储了相同的字符串常量区的地址
  1. 字符串常量区,存在常量区中

你可能感兴趣的:(*NSString 内存存储解析)