Objective c 将给定编码中的字节序列附加到CFMutableString

Objective c 将给定编码中的字节序列附加到CFMutableString,objective-c,macos,Objective C,Macos,我有一个CFMutableString对象,我想在该对象上附加一个给定编码的字节序列(UTF-8、UTF-16、UTF-16LE、UTF-16BE等) 我拥有的最有效的方法是: CFStringRef tmp = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, bytes, numBytes, encoding, NO, kCFAllocatorNull); CFStringAppend(myMutableString, tmp); CFRe

我有一个CFMutableString对象,我想在该对象上附加一个给定编码的字节序列(UTF-8、UTF-16、UTF-16LE、UTF-16BE等)

我拥有的最有效的方法是:

CFStringRef tmp = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, bytes, numBytes, encoding, NO, kCFAllocatorNull);
CFStringAppend(myMutableString, tmp);
CFRelease(tmp);

有更好的方法吗?

我假设您实际上是在询问效率(如CPU时间),并且您的字符串构建确实存在瓶颈。我将按可能性的降序抛出一些有用的想法

通常,您将一组内容附加到一个大字符串中,通过使用
cfstringcreatebycombingstrings
/
-[NSArray componentsjoinedbything:
,您可以将时间缩短20-50%

CFStringRef tmp = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, bytes, numBytes, encoding, NO, kCFAllocatorNull);
CFStringAppend(myMutableString, tmp);
CFRelease(tmp);    
…这样做:

CFStringRef tmp = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, bytes, numBytes, encoding, NO, kCFAllocatorNull);
CFArrayAppendValue(myMutableArray, tmp);
CFRelease(tmp);
// ... after you've finished accumulating everything
CFString *myString = CFStringCreateByCombiningStrings(kCFAllocatorDefault, myMutableArray, kEmptyString);
有时,您知道最终将使用的字符串的大小,并且可以通过在对
CFStringCreateMutable
/
-[NSMutableString stringWithCapacity:
的初始调用中使用适当的容量来将时间缩短一点。当然,此优化与阵列连接不兼容

您可以避免一些转换成本,如果不使用数组连接,还可以避免一些临时的
CFString
创建成本

显然,右端的UTF-16与
CFString
的“字符”是一样的,所以您可以使用
cfstringcreatewithcharactersnopcopy
。或
CFStringAppendCharacters

对于错误的末端UTF-16,“NoCopy”没有帮助,甚至可能会有一点伤害。此外,通过将字节交换到右端UTF-16,您可以比通用转换更快地完成某些事情,特别是如果您可以就地完成的话。我不认为这会更快(特别是在大字符串上),但如果这真的是一个瓶颈,那么绝对值得尝试和计时

将指针移动2个字节后,以UTF-16为前缀的BOM表为一个或另一个

对于UTF-8来说,“NoCopy”同样没有帮助,可能会有点伤害。但是你显然需要做一个转换。虽然您可能能够找到/编写比CF更快的解码器,但它似乎比使用错误的endian UTF-16的可能性要小得多。但是您仍然可以使用
CFStringAppendCString
跳过临时字符串

也有可能,尽管可能性不大,其他一些Unicode库,如
iconv
icu
能够以足够大的优势击败CF,值得一试。如果是这样,请先将所有内容输入右端UTF-16,然后
CFStringCreateWithCharacters
(如果使用数组联接)或
CFStringAppendCharacters
(如果不是)

分配程序和重新计数总是有一些技巧。如果为字符串和数组存储创建一个区域分配器,并创建一个不做任何事情的CFArrayCallbacks,则只需几个malloc调用,几乎不需要重新计数,就可以构建所有内容,只需将所有内容放在区域的地板上,并在执行
组件joinedbystring:
(当然,它使用默认分配器)后释放它们


当然,有了一些额外的应用知识,各种事情都可能发生。举一个非常明显的例子,假设您附加了一组字符串,这些字符串都是16字节值的十六进制编码。在这种情况下,只需分配一大块32*n+1
unichar
,通过复制(右端UTF-16)、从指针偏移量复制1字节(错误的端UTF-16)或将字节与0交替(UTF-8)来“解码”UTF,然后做一个大的
cfstringcreatewithcharactersnopcopy

为什么不使用
NSMutableString*
和friends?注意,它会使这个模式更少的线(嗯,<代码> CfReLasee()/Case>会消失),但它可能更容易维护/读取?但需要修改的代码太多了。也许我会先把它修好。谢谢。我想我是在担心(我已经开始迁移一些类了)。但它回答了我的问题。CF对某些深奥的情况很有用,但是——一般来说——坚持使用NS*+ARC会减少代码行数。如果使用CF,这不是什么ObjC问题,它只是一个C问题……所谓“最有效”和“更好”,是指“更少的CPU时间”吗?如果不是,你是什么意思?如果是这样,这实际上是一个瓶颈吗?整个循环是什么样子的?(显然,将10000个不同编码的字符串附加到一个大字符串中的最有效方法可能不是将10000个字符串分别附加到另一个相同编码的字符串中的最有效方法。)