Правильное управление памятью при добавлении в NSString - PullRequest
0 голосов
/ 15 ноября 2011

У меня есть NSString объект, который я выделил. Я хочу добавлять к этой строке время от времени на протяжении всей жизни приложения Я запутался в том, как правильно обращаться с памятью в примере ниже. Благодаря.

  1. Нужно ли мне сохранять строку, которую я добавляю каждый раз, или можно добавить строку, принадлежащую пулу авто-выпусков, когда stringByAppendingString: возвращает?
  2. Утечка памяти, которая была ранее присвоена my_string каждый раз, когда я делаю добавление?

Код:

NSString* my_string = [[NSString alloc] initWithString:@"Initial string"];
NSString* something = [NSString stringWithFormat:@"%@", @" with something"];
my_string = [[my_string stringByAppendingString:something] retain];
NSString* something_else = [NSString stringWithFormat:@"%@", @" and something_else"];
my_string = [[my_string stringByAppendingString:something_else] retain];
[my_string release];

Ответы [ 3 ]

3 голосов
/ 15 ноября 2011
NSString* my_string = [[NSString alloc] initWithString:@"Initial string"];

не выпускается автоматически (так как оно создается методом init ..., это соглашение), его retainCount равно 1.

NSString* something = [NSString stringWithFormat:@"%@", @" with something"];

автоматически выпускается.

нормально ли добавлять строку, которая принадлежит пулу авто-релизов, как stringByAppendingString: возвращает

До тех пор, пока вы ожидаете, что она будет жить для даОднако в вашем коде:

NSString* my_string = [[NSString alloc] initWithString:@"Initial string"];
NSString* something = [NSString stringWithFormat:@"%@", @" with something"];
my_string = [[my_string stringByAppendingString:something] retain];

у вас есть утечка.Вы должны автоматически освободить my_string перед повторным назначением.Таким образом, последняя строка должна быть:

my_string = [[[my_string autorelease] stringByAppendingString:something] retain];

в противном случае вы навсегда потеряли указатель на объект, который вы должны освободить.Поскольку вы сохраняете результат, вы несете ответственность за его освобождение, поэтому у вас также есть утечка в строке до последней, которая должна быть

my_string = [[[my_string autorelease] stringByAppendingString:something_else] retain];
1 голос
/ 15 ноября 2011

Главное, что нужно иметь в виду, это то, что NSString является неизменным. Независимо от того, выделяете ли вы, создаете в формате или добавляете, вы всегда получаете возвращаемый строковый объект new . Итак, давайте разберем это:

NSString* my_string = [[NSString alloc] initWithString:@"Initial string"];
//String object created with "Initial string" content. Retain +1

NSString* something = [NSString stringWithFormat:@"%@", @" with something"];
//String object created with content " with something" and autoreleased.

my_string = [[my_string stringByAppendingString:something] retain];
//String object created with content "Initial string with something", autorelesed, and retained. Effective retain +1
//Assignment replaces old "Initial string" reference. "Initial string" object still has retain of +1, so it doesn't get deallocated (it leaks).

NSString* something_else = [NSString stringWithFormat:@"%@", @" and something_else"];
//String object created with content " and something_else" and autoreleased.

my_string = [[my_string stringByAppendingString:something_else] retain];
//String object created with contents "Initial string with something and something_else", autoreleaased, and retained. Effective retain +1
//Assignment replaces old "Initial string with something" reference. "initial string with something" object still had a retain of +1, so the object leaks.

[my_string release];
//String object "Initial string with something and something_else" released. Retain -1. Object is deallocated and doesn't leak.

//...Sometime later at the end of the runloop, the autorelease pool is drained and " with something" and " with something_else" are both deallocated.

Итак:

  1. Да. Можно добавить автоматически освобожденную строку. release не вызывается для автоматически освобожденного объекта до конца цикла выполнения, который, по крайней мере, после завершения этого метода.

  2. Да, вы просачиваете объекты, которые ранее были назначены на my_string каждый раз, когда вы делаете добавление ... но это не добавление, которое вызывает утечку, это назначение. Вы можете назначить nil на my_string, а оставшийся объект my_string, на который указывал, все равно будет протекать, если вы не release или autorelease сначала.

0 голосов
/ 15 ноября 2011

Во втором назначении вы теряете сохраненную ссылку первого вызова stringByAppendingString, поэтому:

  1. Можно добавить строку без вызова сохранения, если только вам не требуетсязначение позже в коде.
  2. Да, каждый вызов stringByAppendingString возвращает новую автоматически выпущенную строку.Не сохраняйте его, если вы временно используете значение.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...