iOS面试题+基础知识iOS学习笔记

iOS 刷新对 NSString 字符串 的认知

2020-12-15  本文已影响0人  BlackStar暗星

首先字符串其实是有很多种类型的,如
__NSCFConstantString
__NSCFString
NSTaggedPointerString

初始化字符串的几个方法:

//__NSCFConstantString ,内存在数据区
NSString * str = @"hello world";

// __NSCFString类型,内存在堆区,autorelease 型
NSString * str = [NSString stringWithFormat:@"nicknicknick"];

// NSTaggedPointerString类型,内存在栈区
NSString * str = [NSString stringWithFormat:@"nick"];

// __NSCFString类型,内存在堆区
NSString * str = [[NSString alloc]initWithFormat:@"nicknicknick"];

// NSTaggedPointerString类型,内存在栈区
NSString * str = [[NSString alloc]initWithFormat:@"nick"];

说明

对于 stringWithFormat 和 [[NSString alloc]initWithFormat] 而言,如果初始化的 ‘字符串’ 长度不超过 11 位,(位数不确定,我这个例子是11位,必须是字母,汉字不可以 )那么类型就是 NSTaggedPointerString 否则是 __NSCFString ,如果使用 NSString *xxx = @"xxx" 直接赋值 ,那么不管长度多少,类型都是 __NSCFConstantString
注释:对于字符串多长才改变字符串类型,这个是不固定的,但是具体的规则我没弄清楚,比如说aaaaaaaa12 ,虽然只有10位,但是他是__NSCFString类型,具体怎么改变。猜测:可能跟存储有关,因为TaggedPoint是将值存在了指针里,如果指针占用的内存不够存储其值了,就会改变

验证

WechatIMG18065.png
WeChat2af3825cde63f53ea222f96da1da3052.png

关于字符串判等和地址的问题

首先要知道,== 是对地址的比较

// 情况一
NSString * firstName = [[NSString alloc]initWithFormat:@"nicknicknicknick"];
NSString * secondName = [[NSString alloc]initWithFormat:@"nicknicknicknick"];

if (firstName == secondName) {
  NSLog(@"相等:%p == %p",firstName,secondName);
}else{
  NSLog(@"不相等:%p == %p",firstName,secondName);
}
//地址不相等
打印:不相等:0x6000021ee670 == 0x6000021ee550


// 情况二 ----------------------------------------------------------------
NSString * firstName = [[NSString alloc]initWithFormat:@"nick"];
NSString * secondName = [[NSString alloc]initWithFormat:@"nick"];
// 地址相等
打印:相等:0xde6fb5b6280d4ec0 == 0xde6fb5b6280d4ec0


// 情况三 ----------------------------------------------------------------
NSString * firstName = @"nick";
NSString * secondName = @"nick";
// 地址相等
打印:相等:0x10918fa88 == 0x10918fa88

总结

系统对字符串是有优化的,如果是在 数据区或者栈区 的 字符串,对于值相同的字符串,会使用同一份内存地址,也就是一个字符串对象,在判等的时候,就会相等,如果是在堆区,也就是我们自己管理内存,才会使用新的内存地址去存储新的对象,所以即便 字符串的 value 相同,但是也不是同一个对象。

上一篇下一篇

猜你喜欢

热点阅读