Назначение свойств Objective-C без @property

В настоящее время я разрабатываю приложение для iOS, которое было запущено другим разработчиком.

Обычно я создаю свойство для каждой переменной экземпляра (присвоить int, bool и т. Д. / Сохранить для всех классов).

Итак, в моих проектах эта строка вызывает утечку:

myVar = [[NSString alloc] init]; (alloc/init +1, retain in setter +1, release in dealloc -1 => +1)

Поэтому я использую:

NSString *tmpMyVar = [[NSString alloc] init];
[self setMyVar: tmpMyVar];
[tmpMyVar release];

Or:

NSString *tmpMyVar = [[[NSString alloc] init] autorelease];
[self setMyVar: tmpMyVar];

В этом новом проекте предыдущий разработчик не использовал @ property / @ synthesize, поэтому мне интересно, каков будет результат предыдущей строки кода в этом контексте (я думаю, он не вызывает сеттер)? Утечка памяти?

Предыдущий разработчик выпускает переменную в методе dealloc, как и я.

Большое тебе спасибо!


person Thomas Lupo    schedule 21.08.2012    source источник
comment
Не могли бы вы показать нам пример метода установки, который написал ваш предшественник?   -  person waldrumpus    schedule 21.08.2012


Ответы (2)


Поскольку он напрямую назначает переменную экземпляра выделенному объекту, он сохраняет счетчик равным 1 (потому что, как вы сказали, сеттер не вызывается). И поскольку он выпущен в режиме dealloc, все это сбалансировано. Так что никаких утечек памяти.

Итак, в моих проектах эта строка вызывает утечку:

myVar = [[NSString alloc] инициализация]; (выделение / инициализация +1, сохранение в установщике +1, освобождение в освобождении -1 = ›+1)

Нет, этого не будет даже в ваших проектах, потому что, как вы указали, сеттер не используется.

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

Чтобы проверить наличие сомнительных утечек памяти, таких как ваш пример, также используйте статический анализатор clang или инструмент утечки инструмента.

person Mario    schedule 21.08.2012
comment
Когда я говорю в своих проектах, эта строка вызывает утечку. Это означает, что в моих проектах, которые используют @ property / @ synthesize, а не в этом проекте. Так что, даже если метод другого разработчика не вызывает утечки, является ли это хорошим методом? - person Thomas Lupo; 21.08.2012
comment
Аф @Mario говорит, что этот код не просочится даже в ваш проект. Вы получаете доступ к myVar напрямую, а не через сеттер, поэтому этот код будет правильным и не будет утечкой. myVar = [[NSString alloc] init]; - предпочтительный способ инициализации ivar в методе init *, независимо от наличия или отсутствия сеттеров / получателей и объявлений свойств. - person Analog File; 21.08.2012
comment
В этом проекте это не вызовет утечки из-за отсутствия установщика (без сохранения / без +1), но в проектах, которые используют свойство / синтезировать, это вызывает утечку с использованием myVar = [[NSString alloc] init]; (alloc / init +1, неявный вызов установщика +1, освобождение в dealloc -1)? Нет ? - person Thomas Lupo; 21.08.2012
comment
Нет еще! Взгляните, пожалуйста, на то, что уже неоднократно говорилось! iVar = [[NSString alloc] init] и более поздние версии (например, в dealloc) [iVar release] не протекают! Никогда! Как вы сказали, не существует неявного вызова сеттера. Сеттер называется либо [self setIVar: ...], либо self.iVar = .... iVar = ... не является установщиком, а напрямую обращается к переменной экземпляра! - person Mario; 21.08.2012
comment
Большое тебе спасибо! Это была путаница между iVar = [[NSString alloc] init] и self.iVar = [[NSString alloc] init] - person Thomas Lupo; 21.08.2012
comment
@ThomasLupo: при прямом использовании переменной экземпляра не забудьте освободить myVar перед ее назначением. В противном случае, если он уже указывал на объект, то этот объект будет пропущен. Синтезированный сеттер сделает это за вас. - person newacct; 21.08.2012

Вам нужно посмотреть на реализацию установщика другого разработчика. Убедитесь, что они освобождают существующее значение и сохраняют новое значение; что-то типа:

- (void)setMyString:(NSString *)string
{
    [string retain];
    [_string release];    // ivar
    _string = string;
}

Единственное преимущество реализации ваших собственных методов установки / получения - это делать что-то (кроме установки ivar), когда значение установлено. Если методы не делают ничего подобного, почему бы не изменить все реализации на @property/@synthensize?

person trojanfoe    schedule 21.08.2012
comment
Другой разработчик не написал свой собственный геттер / сеттер. Похоже, он не использовал геттер / сеттер (только прямое назначение) - person Thomas Lupo; 21.08.2012
comment
@ThomasLupo Значит, вам нужно решить настоящие проблемы с управлением памятью. - person trojanfoe; 21.08.2012
comment
Н, почему? Вам не НУЖНЫ сеттеры или геттеры, но они упрощают управление памятью. - person Mario; 21.08.2012
comment
@Mario проще = меньше проблем. - person trojanfoe; 21.08.2012