2013-03-05 2 views
0

Пожалуйста, смотрите код следующим образом:Кто должен отвечать за выпуск параметра сеттера?

- (void) setSomeThing:(NSString *) someThingNew 
{ 
    if(someThing!=someThingNew) 
    { 
     [someThingNew retain]; 
     [someThing release]; 
     someThing = someThingNew; 
    } 
} 

... ... 
- (void) dealloc 
{ 
    [someThing release]; 
    [super dealloc]; 
} 
@end 

Параметр сеттер someThingNew был retain в методе сеттер, что означает его сохранить отсчет 1.

Здесь вопрос: это someThingNew должен release?

Или потому, что someThing и someThingNew указывают на тот же объект, и в dealloc методе someThing уже был release так someThingNew пункт nil?

+3

Objective C руководство управления памятью: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html – Kreiri

ответ

1

- это что-то, что нужно добавить?

Нет, потому что сейчас someThing и someThingNew указывает на тот же адрес. Отпустив someThing в dealloc (и запустив его, чтобы быть в безопасности, но это для другого вопроса), вы сохраняете баланс в сеттере. Все работает отлично *

* Sidenote: Экземпляры NSString обычно copy «d, не retain d, в сеттеров, так что не имеет значения, если вы случайно передать NSMutableString к нему.

+0

Первое спасибо, но что означает «itr»? – Michael

+0

Мои извинения, я случайно набрал «r» вместо периода. – CodaFi

+0

sidenote is great :) –

0

Всякий раз, когда ваш метод сеттера называется someThingNew, сохраняется, а someThing освобождается. Затем новый адрес someThingNew хранится в someThing, что делает отсчет сохранения равным 1.

Это остается за классом, пока сам объект не будет освобожден. После того, как dealloc называется указателем someThingNew, освобождается, делая количество удержания равным 0.

+0

Так что означает [что-то релиз] на самом деле релиз someThing и someThingNew. Большое большое спасибо. – Michael

0

Ваш код верный: сеттер должен сохранять объект, если вы хотите сделать его «сильной» переменной. Но вам не нужно его выпускать: это не область ответственности сеттера. Таким образом, в коде, из которого вы звоните, вы будете:

  • Выделить объект, который будет назначен;
  • Позвоните в сеттер;
  • Отпустите его, когда он вам больше не нужен.

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

Пример:

NSAutoreleasePool* pool=[[NSAutoreleasePool alloc]init]; 
NSString* newString= [[NSMutableString alloc]initWithString: @"Hello"]; // Retain count 1. 
[newString autorelease]; // Still 1 as retain count, but it will be decreased 
         // when the pool will be drained. 
[object setSomeThing: newString]; // Retain count 2. 
[pool drain]; // Retain count 1 

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

Копирование объекта

Если скопировать объект, то способ, как вы называете метод (так приведенный выше код) не изменится, она будет просто изменить реализацию метода. Что-то вроде этого:

- (void) setSomeThing:(NSString *) someThingNew 
{ 
    if(someThing!=someThingNew) 
    { 
     [someThing release]; // Retain count decreased by 1. 
     someThing = [someThingNew copy]; // Retain count 1. 
    } 
} 

... ... 
- (void) dealloc 
{ 
    [someThing release]; 
    [super dealloc]; 
} 
@end 
+0

В самом первом месте я задам два вопроса: это первое, второе - между сохранением и копированием. Вы просто отвечаете им вместе. Я действительно хочу проголосовать за ваш ответ, но у меня недостаточно репутации. Спасибо за работу. – Michael

+0

Копия создает другой объект с собственным счетом. Когда вы создаете новый объект, у него есть счет сохранения 1. Скопированный объект, конечно, будет находиться в другой области памяти, чем исходная. Я добавил пример. –

+0

Спасибо! Вот вопрос: вы не выпустили someThingNew в методе dealloc, вы имеете в виду, что SomeThingNew должен выпускаться в другом месте? – Michael

Смежные вопросы