我的理解是
NSString *s1=[NSString stringWithFormat:@"ios"];
NSString *s2=[NSString stringWithFormat:@"ios"];
s1和s2的地址是不同的,因为存放在堆内存中而不是常量池中。
但是当我NSLog(@"%p\n%p",s1,s2];
发现两者的地址是相同的,难道不是只有@"ios"和@"ios"地址才会相同吗?为什么使用
stringWithFormat后两者地址仍旧是相同的?
你这理解不对,只有在
NSString *str1 = [[NSString alloc]initWithFormat:@"iOS"];
NSString *str2 = [[NSString alloc]initWithFormat:@"iOS"];
这样他们的内存地址才会不一样,因为这个时候单独自己在堆栈里请求地址,而你那个stringWithFormat则是系统在堆栈里请求地址,如果 @“”里的值一样,系统不会再分配地址
堆上指针也可能优化。看到都是常量字符串。就共用
编译器在编译的时候对于可以直接求值的常量,直接编译成常量了,虽然你用了stringWithFormat但是后面的ios不是变量,所以还是可以求值的。
求值后的常量,就可以放在常量池里了,虽然你用了指针,但是并没有放在堆上。运行时需要求值才放在堆上。