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



是否有一个功能在IOS Api中,就像substringFromIndex使用更少的内存(我使用非常非常大的字符串)。如果我必须求出这个函数我该怎么做呢?

Thanks in advance

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

你应该这样做:

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. 它将非常大的字符串作为一系列字节;我相当确定这实际上不会复制字节,但一定要使用仪器来验证。如果您可以将这个超长字符串作为NSData而不是NSString开始,那么您可以更加确信没有任何内容将被复制。
  2. NSData
  3. 获取实际字节缓冲区
  4. 通过使用一些指针算法索引到字节缓冲区
  5. 计算剩余缓冲区的大小
  6. 用字节缓冲区创建一个新的NSString,但告诉它NOT复制字节,并在NSString被释放时NOT释放缓冲区

那么,为什么这很危险呢?基本上,如果字节缓冲区从NSStrings下面消失,可能会发生坏事情(可能崩溃)。

然而,如果你足够聪明,这将允许你创建子字符串而不复制底层字节。


狡猾认为:

可以使veryLargeString成为substring上的一个保留关联对象(即,基本上使substring成为veryLargeString的所有者)。这将确保veryLargeString的生存时间至少和substring一样长。你可以这样做:

static char ParentStringKey;
objc_setAssociatedObject(substring, &ParentStringKey, veryLargeString, OBJC_ASSOCIATION_RETAIN);

substring被释放时,它也会自动释放在veryLargeString上的保留。

最新更新