Да, это так, что он может сделать уникальную копию, не затрагивая существующие данные. Синтезированные сеттеры по сути выглядят так:
// For @synthesize(nonatomic, retain) foo:
- (void) setFoo(NSFoo *theFoo)
{
[theFoo retain]; // retain new value
[foo release]; // release old value, if any
foo = theFoo; // assign new value
}
// For @synthesize(nonatomic, copy) foo:
- (void) setFoo(NSFoo *theFoo)
{
NSFoo* newFoo = [theFoo copy]; // make copy
[foo release]; // release old value, if any
foo = newFoo; // assign new value
}
Обратите внимание, что порядок операций здесь важен - новое значение должно быть сохранено / скопировано до того, как старое значение будет выпущено, в случае самостоятельного присвоения. Если вы сначала отпустили, а затем присвоили это свойство себе, вы можете случайно удалить это значение. Также обратите внимание, что если старое значение nil
, отправка сообщения release
в порядке, так как отправка сообщения объекту nil
явно разрешена и ничего не делает.
Выбор сохранения по сравнению с копированием просто определяет, будет ли свойство объекта иметь то же значение, что и то, к которому вы его устанавливаете. Рассмотрим следующий код:
// suppose the 'foo' property is declared 'retain' and the 'bar' property is
// declared 'copy'
NSFoo *foo = ...;
NSBar *bar = ...;
someObject.foo = foo;
someObject.bar = bar;
[foo changeInternalState]; // someObject.foo also changes, since it's the same object
[bar changeInternalState]; // someObject.bar does NOT change, since it's a copy