Objective-C: @property и @synthesize и утечки памяти - PullRequest
2 голосов
/ 17 декабря 2011

Я пытаюсь понять некоторые проблемы управления памятью. И нашел этот вопрос , который частично отвечает на мой вопрос.

Например, в MyObject у меня есть переменная экземпляра, объявленная как свойство и правильно синтезированная в файле реализации:

 @interface MyObject : NSObject
    ...
    ObjectA objA;
    ...
    @property (nonatomic, retain) ObjectA *objA;
@end

В какой-то произвольный момент я создаю экземпляр objA. Я знаю, self.objA = _objA; вызывает синтезированный метод доступа. Что, по логике, означает, что self.objA = [[ObjectA alloc] init]; приведет к утечке памяти, поскольку счет сохранения будет на один больше, чем предполагалось (я знаю, что проверка счетчика хранения напрямую не является точным способом проверки того, как долго объект будет в памяти ).

objA = [[ObjectA alloc] init; также вызывает сеттер и может привести к утечке памяти?

Ответы [ 3 ]

4 голосов
/ 17 декабря 2011

Называя имя свойства без "себя".пропускает установщик и обновляет переменную экземпляра напрямую.

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

@synthesize objA = _objA;

Ваш классбудет выглядеть так:

@interface MyObject : NSObject
    ...
    @property (nonatomic, retain) ObjectA *objA;
@end

Теперь, если вы забудете «self», вы получите ошибку компилятора, и вам будет более четко указано, какую переменную вы на самом деле используете.

3 голосов
/ 17 декабря 2011

Назначение результата alloc / init для необработанной переменной экземпляра является вполне приемлемым и рекомендуется для установки переменных экземпляра в методе инициализации.Чтобы избежать утечки памяти при использовании синтезированных сеттеров, вы можете использовать два подхода:

1.Autorelease

self.objA = [[ObjectA alloc] init] autorelease];

Пройдя через установщик свойства 'retain', увеличивается счетчик сохранения.Выделение / инициализация также увеличивало количество сохраняемых данных, но уравновешивалось автоматическим выпуском, что означает, что оно будет уменьшено на 1 и конец цикла текущего события.


2.Сначала назначьте временную переменную

// +alloc/-init increments the retain count of objectA to 1
ObjectA objectA = [[ObjectA alloc] init]; 

// Synthesized setter calls retain on objectA, incrementing to 2.
self.objA = objectA; 

// Decrement objectA's retain count to 1.
[objectA release]; 
2 голосов
/ 17 декабря 2011

objA = [[ObjectA alloc] init]; не использует метод установки, но устанавливает переменную экземпляра напрямую. Таким образом, счет удержания будет равен 1 из alloc.

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