要回答您的问题,我们可以尝试在创建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