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的區別特別大