Используйте свойство в расширении класса вместо ivar в сообщении ARC

Рекомендуемой практикой является использование свойств, в том числе приватных, через расширение класса вместо ivar (кроме init и Dealloc) в пост-ARC-окружении.

Помимо рекомендуемой практики, каковы основные недостатки использования ivar вместо свойства? Я пытаюсь убедить некоторых людей переключиться, но некоторые утверждают, что ivar работает так же хорошо и быстрее. Поэтому я хотел бы собрать веские убедительные аргументы, а не давать мягкие утверждения, такие как «это лучше, более последовательно и т. д.».


person Boon    schedule 24.05.2014    source источник


Ответы (3)


На ваш вопрос нет правильного ответа, только мнения. Таким образом, вы получите разные ответы, вот один, чтобы добавить в свою коллекцию :-)

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

Общедоступное свойство является частью инкапсуляции класса — то, как реализовано свойство (или метод), не имеет значения для пользователя, важно только поведение.

Классу не нужно скрывать от самого себя, как он реализован!

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

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

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

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

ХТН

person CRD    schedule 24.05.2014
comment
Это рекомендуется в соответствии с документами Apple по инкапсуляции. Лучше всего использовать свойство объекта каждый раз, когда вам нужно отслеживать значение или другой объект. Это устарело или не относится к «частной» собственности? - person Logan; 25.05.2014
comment
Ссылка в первую очередь касается инкапсуляции, и ранее в ней говорилось: Учитывая, что один из основных принципов объектно-ориентированного программирования заключается в том, что объект должен скрывать свою внутреннюю работу за своим открытым интерфейсом, важно получить доступ к свойства, используя поведение, предоставляемое объектом, вместо того, чтобы пытаться получить доступ к внутренним значениям напрямую. Он не исключает частные свойства, но охватывает объявление переменных экземпляра в @implementation функции, которая была введена в Obj-C после свойств... - person CRD; 25.05.2014
comment
Спасибо за разъяснения :) - person Logan; 25.05.2014

По производительности особой разницы нет. На самом деле свойства — это переменные экземпляра с генерируемыми методами доступа. Таким образом, причина, по которой вы хотите создавать свойства, заключается в том, что код для генерации уведомлений KVO и методы установки/получения создаются для вас. Таким образом, у вас будет меньше времени на повторяющийся код во всех ваших классах.

person J2theC    schedule 24.05.2014
comment
Есть ли когда-нибудь необходимость КВО в частную собственность? Кроме того, зачем вам сеттер/геттер, если вам не нужно специальное поведение? - person Boon; 25.05.2014

Есть несколько случаев, когда использование частного свойства лучше или требуется по сравнению с использованием переменной экземпляра:

  1. KVO. Поскольку для работы KVO требуются методы getter/setter, вам нужно свойство (технически только методы). Использование KVO на частной территории, вероятно, не слишком распространено.
  2. Ленивая загрузка или другая «бизнес-логика» вокруг значения. Использование свойства с пользовательскими методами установки/получения позволяет применять ленивую загрузку и/или другую логику/проверку значения.
  3. Доступ к значению внутри блока по слабой ссылке.

Последний пункт лучше всего осветить на примере. Как многие знают, при определенных условиях в блоке можно создать цикл ссылок, который можно разбить, используя слабую ссылку на self. Проблема в том, что вы не можете получить доступ к ivar, используя слабую ссылку, поэтому вам нужно свойство.

__weak typeof(self) weakSelf = self;
[self.something someReferenceCycleBlock:^{
    weakSelf->_someIvar = ... // this gives an error
    weakSelf.someProperty = ... // this is fine
}];

По сути, используйте ивар, если ни один из этих пунктов никогда не будет применяться. Используйте частные свойства, если какие-либо из них могут применяться в течение всего времени существования класса.

person rmaddy    schedule 24.05.2014
comment
Просто хотел прокомментировать, что если вы конвертируете weakSelf в strongSelf, вы можете установить Ivars через strongSelf->_someIvar. - person Logan; 25.05.2014
comment
Отличное предложение, которое я не рассматривал. Спасибо. - person rmaddy; 25.05.2014
comment
@rmaddy, есть ли когда-нибудь необходимость в КВО в частной собственности? - person Boon; 26.05.2014
comment
Возможно, в KVO нет необходимости, но может потребоваться знать, когда значение изменяется, и это лучше всего сделать с помощью специального установщика для частного свойства. - person rmaddy; 26.05.2014
comment
Так что можно утверждать, что когда есть необходимость в КВО, то вместо ивара используйте свойство. Для обычного использования ivar вполне подходит, верно? - person Boon; 27.05.2014
comment
В моем ответе в основном говорится, что используйте ivar, если вам не нужно свойство по причинам, которые я перечислил. Или всегда используйте свойства. Тебе решать. - person rmaddy; 27.05.2014