要回答您的問題,我們可以嘗試在創建CTLine
之前和之後查看字符串的引用計數。我們也可以嘗試在更改字符串之前和之後打印行的描述。
CFMutableAttributedStringRef mas = CFAttributedStringCreateMutable(NULL, 0);
CFAttributedStringReplaceString(mas, CFRangeMake(0, 0), CFSTR("world"));
CTLineRef line = CTLineCreateWithAttributedString(mas);
NSLog(@"mas count = %ld", CFGetRetainCount(mas));
NSLog(@"line before change = %@", line);
CFAttributedStringReplaceString(mas, CFRangeMake(0, 0), CFSTR("hello "));
NSLog(@"line after change = %@", line);
這往往徒勞無功看對象的保留計數,但在這種情況下,它的信息:
2012-08-03 12:11:10.717 coretext[44780:f803] count before creating line = 1
2012-08-03 12:11:10.720 coretext[44780:f803] count after creating line = 1
由於保留數爲1的前後,而我自己的引用(因爲CFAttributedStringCreateMutable
給我一個擁有參考),我知道我是字符串的唯一所有者,在創建CTLine
之前和之後。所以CTLine
不保留字符串。這是不太可能的,它保留一個參考字符串,而不保留它。
這裏的改變串前行的描述:
2012-08-03 12:11:10.721 coretext[44780:f803] line = CTLine: run count = 1, string range = (0, 5), width = 28.6758, A/D/L = 9.24023/2.75977/0, glyph count = 5
{
CTRun: string range = (0, 5), characters = { 0x0077, 0x006f, 0x0072, 0x006c, 0x0064 }, attributes =
<CFBasicHash 0x6d69ce0 [0x1227b38]>{type = mutable dict, count = 1,
entries =>
2 : <CFString 0xab1b0 [0x1227b38]>{contents = "NSFont"} = CTFont <name: Helvetica, size: 12.000000, matrix: 0x0>
CTFontDescriptor <attributes: <CFBasicHash 0xd345ed0 [0x1227b38]>{type = mutable dict, count = 1,
entries =>
1 : <CFString 0xabbd0 [0x1227b38]>{contents = "NSFontNameAttribute"} = <CFString 0x6d69720 [0x1227b38]>{contents = "Helvetica"}
}
>
}
}
我注意到,描述不包括字符串,但包括字符數組。所以該行可能不會保留字符串的副本;它解析字符串以創建它自己的私人表示。
下面是改變後的字符串行的描述:
2012-08-03 12:11:10.722 coretext[44780:f803] line = CTLine: run count = 1, string range = (0, 5), width = 28.6758, A/D/L = 9.24023/2.75977/0, glyph count = 5
{
CTRun: string range = (0, 5), characters = { 0x0077, 0x006f, 0x0072, 0x006c, 0x0064 }, attributes =
<CFBasicHash 0x6d69ce0 [0x1227b38]>{type = mutable dict, count = 1,
entries =>
2 : <CFString 0xab1b0 [0x1227b38]>{contents = "NSFont"} = CTFont <name: Helvetica, size: 12.000000, matrix: 0x0>
CTFontDescriptor <attributes: <CFBasicHash 0xd345ed0 [0x1227b38]>{type = mutable dict, count = 1,
entries =>
1 : <CFString 0xabbd0 [0x1227b38]>{contents = "NSFontNameAttribute"} = <CFString 0x6d69720 [0x1227b38]>{contents = "Helvetica"}
}
>
}
}
我們可以看到,該行並沒有改變其字形計數或它的字符數組。從這裏我們可以得出結論,當你改變字符串時,該行不會改變。您可以通過在更改字符串之前和之後實際繪製線來進一步測試。我把它作爲讀者的練習。
感謝您的信息,這真的很有幫助。 – user1574591 2012-08-03 16:41:20
我閱讀了鏈接的文檔,但我仍然有點掛斷電話。你說CTLineRef創建函數必須保留字符串並且可以複製它,但是它確實影響了我如何處理它。如果它保留它,那麼我不應該修改任何可變字符串。而如果它複製它,那麼我可以修改一個可變字符串。你發佈的鏈接表明它「可能」是一個屬性,「應該」做一個副本,我是否假設CTLineRef做到了這一點,並希望最好?我希望我有一份在這個問題上100%可靠的文件。 – user1574591 2012-08-03 16:53:18
你在這一點上是正確的。我只是說它「很可能會複製」,因爲我不知道這個實現是否真的將CFStringRef複製並存儲爲ivar。它也可能解析輸入字符串並在某些其他數據結構中存儲某些信息。如果複製語義沒有用文字副本實現,則可以保證複製語義。它必須這樣才能保證強大的實施。 – 2012-08-03 16:59:24