сеттер по умолчанию в iOS - PullRequest
0 голосов
/ 28 июня 2011
- (void)setSomeInstance:(SomeClass *)aSomeInstanceValue
{
    if (someInstance == aSomeInstanceValue)
{
    return;
}
SomeClass *oldValue = someInstance;
someInstance = [aSomeInstanceValue retain];
[oldValue release];
}

ок, сеттер должен выглядеть так. Я понимаю первые 3 строки - не допускайте ситуации, когда новый объект совпадает со старым. Но как насчет этой строки:

SomeClass *oldValue = someInstance;

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

  [someinstance release];
   someinstance = [aSomeInstanceValue retain];

Ответы [ 3 ]

2 голосов
/ 28 июня 2011

Я бы посоветовал работать с сеттером по умолчанию примерно так:

- (void) setFoo:(id) foo {
    if ( foo == _foo) return;
    [_foo release];
    _foo = [foo retain];
}

если вы не проверяете, совпадают ли старый и новый foo, вы можете получить ссылку на освобожденный объект, если по какой-то причине напишите что-то вроде этого:

myObject.foo = myObject.foo;

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

2 голосов
/ 28 июня 2011

На самом деле - без причины.

Обычно это просто выбор.

Есть три идиомы для написания аксессоров.

Авто-релиз :

- (void)setFoo:(id)newFoo {
    [foo autorelease];
    foo = [newFoo retain];
}

Меньше кода для записи, но я думаю, что авто-релиз в этом случае ленив.

Сохраните, а затем отпустите

- (void)setFoo:(id)newFoo {
    [newFoo retain];
    [foo release];
    foo = newFoo;
}

Сначала проверьте

- (void)setFoo:(id)newFoo {
    if ([foo isEqual:newFoo]) {
        return;
    }
    [foo release];
    foo = [newFoo retain];
}

Единственное различие между двумя последними состоит в том, что второй проверяет, отличается ли новое значение от текущего значения, прежде чем пытаться установить свойство.За счет дополнительного оператора if.Итак, если новое значение, вероятно, будет таким же, как и старое, использование этой конструкции даст лучшую производительность.

Как правило, и если вы по каким-то странным причинам не используете свойства, используйте retain затем release,и затем, если профилирование показывает, что есть узкое место - используйте метод проверки первым.

0 голосов
/ 28 июня 2011

Установщик сохранения по умолчанию работает следующим образом:

- (void)setFoo:(Foo *)aFood
{
    if (_foo != nil)
       [_foo release];
    if (aFood != nil)
       _foo = [aFood retain];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...