是否有一个功能在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];
这是在做什么:
- 它将非常大的字符串作为一系列字节;我相当确定这实际上不会复制字节,但一定要使用仪器来验证。如果您可以将这个超长字符串作为
NSData
而不是NSString
开始,那么您可以更加确信没有任何内容将被复制。 - 从
NSData
获取实际字节缓冲区 - 通过使用一些指针算法索引到字节缓冲区
- 计算剩余缓冲区的大小
- 用字节缓冲区创建一个新的
NSString
,但告诉它NOT复制字节,并在NSString
被释放时NOT释放缓冲区
那么,为什么这很危险呢?基本上,如果字节缓冲区从NSStrings
下面消失,可能会发生坏事情(可能崩溃)。
然而,如果你足够聪明,这将允许你创建子字符串而不复制底层字节。
狡猾认为:
可以使veryLargeString
成为substring
上的一个保留关联对象(即,基本上使substring
成为veryLargeString
的所有者)。这将确保veryLargeString
的生存时间至少和substring
一样长。你可以这样做:
static char ParentStringKey;
objc_setAssociatedObject(substring, &ParentStringKey, veryLargeString, OBJC_ASSOCIATION_RETAIN);
当substring
被释放时,它也会自动释放在veryLargeString
上的保留。