是否有像su​​bstringFromIndex这样的函数使用更少的内存?

时间:2011-12-06 23:58:07

标签: iphone string memory substring

在IOS Api中是否有类似substringFromIndex的函数除了使用更少的内存(我使用非常非常大的字符串)。如果我必须做这个功能我将如何去做呢?

提前致谢

1 个答案:

答案 0 :(得分:2)

是的,但它有点迂回且有潜在危险

这是你做的:

NSString *veryLargeString = ...;
NSUInteger startingIndex = ...;
NSData *veryLargeStringData = [veryLargeString dataUsingEncoding:NSUTF8StringEncoding];

const void *bytes = [veryLargeStringData bytes];
const void *subBytes = bytes + startingIndex;
NSUInteger subLength = [veryLargeStringData length] - startingIndex;

NSString *substring = [[NSString alloc] initWithBytesNoCopy:subBytes length:subLength encoding:NSUTF8StringEncoding freeWhenDone:NO];

这是做什么的:

  1. 它将非常大的字符串作为一系列字节;我相当确定这实际上并没有复制字节,但一定要使用Instruments来验证。如果您可以将此超长字符串作为NSData开头而不是NSString,那么您可以更自信地不会复制任何内容。
  2. NSData
  3. 获取实际的字节缓冲区
  4. 使用一些指针算法
  5. 索引到字节缓冲区
  6. 弄清楚剩余多少缓冲区
  7. 使用字节缓冲区创建一个新的NSString,但告诉它 NOT 复制字节,并在<{1>时将 NOT 释放缓冲区已解除分配
  8. 那么,为什么这很危险?基本上,如果字节缓冲区从NSString下方消失,可能会发生Bad Things™(可能会崩溃)。

    但是,如果你对它很聪明,这将允许你创建子串而不复制底层字节。


    狡猾的想法

    您可以在NSStringsveryLargeString保留关联对象(即,基本上将substring设为substring的所有者)。这将确保veryLargeString至少与veryLargeString一样长。你这样做是这样的:

    substring

    取消分配static char ParentStringKey; objc_setAssociatedObject(substring, &ParentStringKey, veryLargeString, OBJC_ASSOCIATION_RETAIN); 后,它还会自动释放substring上的保留。