TaggedPointer
- swift.gg/2018/10/08/…
- 用于存储NSNumber、NSDate、NSString等小对象
- 指针里面存储的数据变成了:Tag + Data,也就是将数据直接存储在指针中
- 当指针不够存储数据时,才会使用动态分配内存的方式来存储数据
- objc_msgSend能识别Tagged Pointer,比如NSNumber的intValue方法,直接从指针提取数据,节省了以前的调用开销
- 如何判断一个指针是否是taggedPointer,以下是objc中相关的代码
- Mac平台,最低有效位为1
- iOS平台,最高有效位为1
#if OBJC_MSB_TAGGED_POINTERS
# define _OBJC_TAG_MASK (1UL<<63)
#else
# define _OBJC_TAG_MASK 1UL
static inline bool
_objc_isTaggedPointer(const void * _Nullable ptr)
{
return ((uintptr_t)ptr & _OBJC_TAG_MASK) == _OBJC_TAG_MASK;
}
- NSString有__NSCFConstantString、NSTaggedPointerString、__NSCFString三种类型
- 用[NSString stringWithFormat:@"xxx"]创建字符串,字符串小于等于9的时候就会被优化成NSTaggedPointerString类型,大于等于10的时候就会变成__NSCFString
- 用string直接创建字符串,就是__NSCFConstantString类型,无论有多长都是
- 发生拼接操作,就一定会变成__NSCFString
String
从一个问题开始,一个String的变量占多少个字节? 答案是16个字节。
- 字符串count <=15时,内存直接存放的是字符串的值(small String,类似于OC中的NSTaggedPointerString)
0x3736353433323130 0xe800000000000000
这个e表示类型,这个8表示有几位
- 字符串count >=16时,前面存储的是string的长度,后面存储是地址
0xd000000000000011 0x8000000100000f80
- 字符串拼接,如果拼接后的字符串还是小于等于15,那么就还是和第一种一样,这个地方和OC的区别特别大