Сохранение / освобождение синтезированного сеттера для оставшегося свойства - PullRequest
3 голосов
/ 22 февраля 2012

Установщик удерживаемого объекта автоматически освобождает объект первым?

Я все еще работаю без ARC, поэтому у меня есть эти вопросы.

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

ObjectClass *anObject_;

с большим количеством

@property (nonatomic, retain) ObjectClass *anObject;

И синтез с использованием

@synthesize anObject = anObject_;

Если у меня есть сеттер, который автоматически синтезируется с использованием атрибута retain, то установщик сначала выполнит деблокирование, если это необходимо ? Примерно так:

- (void) setAnObject:(ObjectClass*)anObject {
    if (anObject_) [anObject_ release];
    anObject_ = [anObject retain];
}

А можно просто назначать объекту, не отпуская его сначала ?

Можно ли освободить объект, присвоив свойству значение nil ? (Это может быть небезопасно, если есть другие владельцы.)

self.anObject = nil;

Другими словами, могу ли я обойтись без кода if (anObject_) [anObject_ release]; вне установщика и позволить синтезированному установщику сделать это для меня ?

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

И последнее: при использовании ARC я предполагаю, что self.anObject = nil; и self.anObject = anthingelse; оба безопасны ? И исходный объект будет освобожден независимо от того, какой у меня код установщика ?

1 Ответ

3 голосов
/ 22 февраля 2012

Ответ почти на каждый ваш вопрос - да. Сохранения и релизы будут добавлены в ваш код, чтобы сделать его правильным. В частности, установщик для свойства strong освободит свое текущее значение и сохранит свое новое значение. Даже если вы не используете синтезированные средства доступа и не пишете свои собственные, они все равно будут вести себя правильно. Действительно, в ARC вам даже не разрешено звонить retain или release в вашем собственном коде.

Одна вещь, в которой вы, кажется, немного запутались, это:

Могу ли я освободить объект, присвоив свойству значение nil? (Это может быть небезопасно, если есть другие владельцы.)

Это правда, что когда вы установите свойство равным nil, release будет вызываться для объекта. Но помните, что это не обязательно означает, что объект будет освобожден: это случается только в том случае, если счет удержания становится равным 0.

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

Существует гораздо более простой способ думать обо всем этом, если вы используете ARC. Забудьте о retain и release и просто подумайте о владении объектом. Объект не будет освобожден, пока какой-либо другой объект владеет им (со ссылкой strong). И действительно, единственная ловушка, которую нужно иметь в виду, это циклы: если два объекта владеют друг другом, они не могут быть освобождены.

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