Можно ли называть release для свойства в Objective C? - PullRequest
3 голосов
/ 01 сентября 2011

Я недавно изучал Objective C и заметил, что следующий шаблон часто используется в руководствах и примерах кода (включая примеры с сайта Apple).

UIView *myUiView = [[UIView alloc] init];
self.uiView = myUiView;
[myUiView release];

Мне было просто интересно, что создание новой переменной - просто расточительство, просто набор свойств. Я также видел, как использовался следующий шаблон, но из того, что я понимаю, считается плохой формой использования автоматического выпуска на устройстве iOS, поскольку пул автоматического выпуска занимает довольно много служебной информации, что может быть нехорошо на мобильном устройстве

self.uiView = [[[UIView alloc] init] autorelease];

Недавно я играл с использованием следующего шаблона, который устанавливает свойство, а затем вызывает release для свойства (чтобы уменьшить счетчик ссылок для самого свойства).

self.uiView = [[UIView alloc] init];
[self.uiView release];

Мне удалось использовать его на нескольких контроллерах ViewController без каких-либо побочных эффектов, но это правильный код или я что-то упустил, что делает его плохой идеей?

Ответы [ 5 ]

1 голос
/ 01 сентября 2011

Нет. Это недействительно.

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

Свойства - это просто пара методов, один из которых устанавливает абстрактную сущность, а другой - получает ее. В целом нет абсолютно никакой гарантии, что получатель выдаст вам тот же объект, который вы только что передали в установщик. Например, если вы передаете изменяемую строку в свойство копирования NSString, вы определенно не вернет тот же объект.

Используйте любой из первых двух шаблонов. Первый ничего не теряет. Вполне вероятно, что локальная переменная будет существовать только в регистре. Служебная нагрузка второго будет длиться до тех пор, пока не истечет следующий пул автоматического выпуска, и будет составлять всего несколько байтов (имейте в виду, что фактический объект будет длиться до self в любом случае).

1 голос
/ 01 сентября 2011

Это недопустимо, и даже в тех случаях, когда оно работает, оно немного «некрасиво», а остальные два просто фиксируют характеристику сохранения свойства, делая счет сохранения 2 после того, как выделение уже делает счет сохранения 1.

Я склонен делать то, что вы описали в первом примере или в следующем.

в моем @interface

@property (nonatomic, retain) UIView *uiView;

в моей @ реализации

@synthesize uiView = _uiView;

затем при настройке свойства.

_uiView = [[UIView alloc] init];
1 голос
/ 01 сентября 2011

Свойство getter - это метод, и он не должен возвращать ivar, он может фактически получить свое возвращаемое значение где угодно, так что вы можете освободить его, но это может быть уже автоматически выданное значение. Если это так, то у вас проблемы.

IOW, если получатель свойства будет делать что-то вроде (не обычно, но возможно и допустимо):

- (NSString *) helloString
{
    return [[myStringIVar copy] autorelease];
}

и вы делаете:

[self.helloString release];

тогда вы потерпели неудачу двумя способами:

  • Вы не выпустили ивар, который хотели выпустить
  • Вы отпускаете автоматически выпущенный объект

ИМО, лучше выпустить ивар напрямую:

[myStringIVar release];
1 голос
/ 01 сентября 2011

Если реализация свойства get для простого возврата ссылки на базовый ivar, то она совершенно эквивалентна, и вы просто уменьшаете счет сохранения выделенного объекта.

С другой стороны, еслиВы не можете быть уверены, что делает получатель (что, если он возвращает что-то иное, чем ивар, например, какой-то вычисленный результат и т. д.), это может быть опасно.

0 голосов
/ 01 сентября 2011

С точки зрения счетчика ссылок, нет ничего плохого в вызове release с использованием значения свойства.Однако есть несколько вещей, которые мне (лично) не понравятся:

Синтаксис свойства - это просто синтаксический сахар для вызовов методов.Итак, на самом деле ваш код выглядит так:

[self setUiView: [[UIView alloc] init]];
[[self uiView] release];

Другая вещь может быть связана с тем, что я думаю странным образом, но мне нравится думать, что счетчики ссылок фактически связаны со ссылками.Локальная переменная, содержащая указатель на мой объект, является такой ссылкой.Наличие этого в коде напоминает мне, что у меня есть кое-что сделать, чтобы очистить вещи должным образом (или, если нет, написать хотя бы короткий комментарий, почему мне не нужно убирать).

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

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