Есть ли такая функция, как substringFromIndex, которая использует меньше памяти? - PullRequest
2 голосов
/ 07 декабря 2011

Есть ли в IOS Api функция, подобная тому, что substringFromIndex исключает, использует намного меньше памяти (я использую ОЧЕНЬ ОЧЕНЬ большие строки). Если бы мне пришлось выполнить эту функцию, как бы я поступил так?

Заранее спасибо

1 Ответ

2 голосов
/ 07 декабря 2011

Да, но это своего рода карусель и потенциально опасно

Вот что вы делаете:

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. Создайте новый NSString с байтовым буфером, но указав NOT скопировать байты и NOT освободить буфер, когда NSString освобожден

Итак, почему это опасно? По сути, если байтовый буфер исчезает из-под NSStrings, могут произойти плохие вещи (вероятно, сбой).

Однако, если вы сообразительны в этом, это позволит вам создавать подстроки без копирования базовых байтов.


Коварная мысль :

Вы можете сделать veryLargeString оставшимся связанным объектом на substring (то есть, по сути, сделать substring владельцем veryLargeString). Это гарантирует, что veryLargeString живет по крайней мере столько же, сколько substring. Вы бы сделали это так:

static char ParentStringKey;

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

Когда substring освобождается, он также автоматически освобождает свое удержание на veryLargeString.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...