iOS中的String

小星星_ios發表於2020-03-27

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

相關文章