Управление памятью со свойствами - PullRequest
0 голосов
/ 31 июля 2009

Я начинаю лучше понимать управление памятью в target-c, но есть кое-что, чего я не понимаю. Это объявление свойства:

@property (nonatomic, retain)UILabel *myLabel;

и это его невидимый синтезатор (я думаю):

- (void)setMyLabel:(UILabel *)newValue {
    if(myLabel != newValue) {
        [myLabel release];
        myLabel = [newValue retain];
    }
}

Что экономит вам всю работу по сохранению и тому подобное каждый раз, но, скажем, я установил свое свойство впервые, оно еще не было выделено, поэтому его счетчик ссылок равен 0, верно? Так что я делаю

UILabel *tempLabel = [[UILabel alloc] init];
self.myLabel = tempLabel;
[tempLabel release];

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

Спасибо !!

Ответы [ 3 ]

6 голосов
/ 31 июля 2009

Я думаю, что вы путаете объекты и ссылки. Свойство - это ссылка на объект, а не сам объект. Когда вы устанавливаете или отменяете свойство, оно отправляет сохраняемые и освобождаемые объекты, на которые оно указывает, но сама ссылка является частью объекта, в котором находится свойство (в данном случае self).

Может быть полезно прочитать о таких вещах, как указатели и lvalues ​​.

0 голосов
/ 01 августа 2009

Начальное значение myLabel - ноль, поэтому ваше первое присвоение свойству, т.е.

self.myLabel = tempLabel;

выпустит ноль, то есть [ноль релиз]. В Задаче C отправка сообщения на nil запрещена, поэтому это ничего не даст.

Аналогично, в вашем методе dealloc вы должны иметь:

[myLabel release];

Что освободит myLabel, если свойство когда-либо было назначено, с балансировкой [newValue retain] в установщике. Если свойство никогда не было назначено, тогда оно все равно будет равно нулю, и снова [nil release] будет неактивным.

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

Объект «исчезнет» (т. Е. Будет освобожден), когда все владения на нем будут оставлены. То есть, когда (или вскоре после этого) все вызовы alloc / copy / new были сбалансированы с вызовами release / autorelease.

0 голосов
/ 31 июля 2009

Я также относительно новичок в Objective-C, но хотел бы попытаться ответить на него, чтобы подтвердить мое понимание.

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

Да, счет удержания равен 0.

В сеттере сначала он освобождается. Так разве это не исчезнет?

Вычитает 1 из счетного остатка myLabel. Если счет сохранения myLabel достигает 0, данные или объект, на которые указывает переменная myLabel, будут освобождены из памяти.

Если его счетчик ссылок равен единице, а затем в установщике он освобождается, как он остается, чтобы установить оставшееся новое значение?

В этом сценарии данные, на которые указывает myLabel, будут освобождены (количество записей будет 0), а myLabel будет указывать на ноль (пусто). Переменная устанавливается в классе и всегда будет доступна для принятия сообщений этому установщику, поэтому новые данные могут быть назначены на myLabel независимо от того, является ли счет myLabel 0 или 100.

...