2009-09-02 3 views
0

Мне немного любопытно узнать о последних строках в двух примерах, представленных ниже (например, planetName = [значение ??????]). Я понимаю, что 1-й пример с копией лучше всего, так как копия string для защиты от исходного исходного объекта, который изменяется в другом месте.Setter: [value copy] или [value release]?

Я также немного смущен последней строкой во втором примере, опять же я понял, что объект значения передавался в метод, я думаю, меня путают, поскольку значение сохраняется без связанного выпуска? Может кто-то меня прямо посадил?

- (void)setPlanetName:(NSString *)value { 
    if (planetName != value) { 
     [planetName release]; 
     planetName = [value copy]; 
    } 
} 

.

- (void)setPlanetName:(NSString *)value { 
    if (planetName != value) { 
     [planetName release]; 
     planetName = [value retain]; 
    } 
} 

ответ

1

Дано:

- (void)setPlanetName:(NSString *)value { 
    if (planetName != value) { 
     [planetName release]; 
     planetName = [value copy]; 
    } 
} 

-copy гарантирует, что если кто-то проходит в экземпляре NSMutableString как value, то planetName не изменится в ваших случаях из-под вас.

Хороший защитный шаблон программирования. Обратите внимание, что -copy свободен от неизменяемых строк; -copy просто ударяет значение сохранения и возвращает self (экземпляр строки, которая была скопирована).

Теперь рассмотрим ваш второй пример:

- (void)setPlanetName:(NSString *)value { 
    if (planetName != value) { 
     [planetName release]; 
     planetName = [value retain]; 
    } 
} 

Прекрасно действует и работает отлично, только не как оборонительный.

В обоих случаях planetName должен быть выпущен в вашем -dealloc способе.

- (void) dealloc 
{ 
    [planetName release]; 
    planetName = nil; // defensive 
    [super dealloc]; 
} 

Это не имеет значения, если строка копируется, сохраняется, или изначально была постоянная строка, которая была передана в вашем инкубаторе. Если вы сохраните его (или подразумеваете сохранить его с помощью копии), вы должны его освободить.

Обратите внимание, что вы можете думать об этом как «escape-шаблоны». Всякий раз, когда существующее значение planetName ускользает от вашего объекта, вы должны его освободить. Это может произойти, когда объект будет освобожден или когда будет установлено новое значение planetName, следовательно, -release в сеттерах.

Или, если в Mac OS X вы можете включить сборку мусора и сделать с ней. В любом случае вы должны использовать @property & @synthesize, чтобы автоматически генерировать пару getter/setter.

+0

Изначально я хочу избежать сбора мусора, чтобы лучше понять как все работает, это также в первую очередь причина, по которой (изначально) я не использую свойство и не синтезирую. Спасибо за помощь, очень ценю. – fuzzygoat

+0

Просто любопытно, если в первой версии я использую постоянную строку @ «Земля» для значения, о котором вы говорили, что копия ударяет значение сохранения, в этом случае это должно быть до 2? Если да, то как они освобождаются, я предполагаю, что с константой строки один хранится в сегменте данных и не нуждается в выпуске, другой - тот, который мы в конечном счете освобождаем от метода dealloc? Просто спрашивайте, как вы сначала имеете «значение», а затем вы делаете копию, так что 2, если я не ошибаюсь. – fuzzygoat

+0

Одним словом, не беспокойтесь об этом и не беспокойтесь о том, чтобы сохранить счет; значение его в любой момент времени является детальностью реализации. Просто убедитесь, что сохраненные вами данные сбалансированы версиями в вашем коде. – bbum

0

в методе dealloc класса, есть должна быть другим [выпуск Planetname] там, который будет обрабатывать освобождение любого переменного экземпляра. Если это присутствует, утечка памяти не беспокоит.

Что касается вашего другого вопроса, то копия используется, если у вас потенциально есть изменяемый объект, который вы не хотите позволять другому коду изменять ваш ожидаемый класс. Ожидается, что вы выпустите любой объект, на который вы вызываете копию, так как он возвращает что-то с сохранением числа 1. Кроме того, в случае неизменяемых объектов (например, NSStrings vs. NSMutableStrings) копирование просто вызывает сохранение, поскольку нет необходимости делать полная копия чего-то непреложного.

+0

Я правильно понял, что в первой версии (с копией), что если значение является строковым литералом (т[email protected] «TanTooine»), затем его автоматически отпущено, если, с другой стороны, значение является объектом, тогда его просто оставили для того, что создало его вне метода для выпуска? – fuzzygoat

+0

, если это строковый литерал, вызывающая копия на нем эффективно сохраняет его (поскольку строковые литералы неизменяемы), поэтому он не будет автоматически выпущен до тех пор, пока класс, которому принадлежит эта строка, не будет dealloc'd – Kevlar