2014-02-20 3 views
0

Почему разрешено объявлять свойства в категориях, когда ни они, ни их методы доступа не синтезируются? Есть ли накладные расходы на производительность?Свойства в категориях

Является категоризацией чисто техникой компилятора?

Я пытаюсь понять, как работают категории. This просто объясняет, что делать и что не делать. Есть ли какие-либо источники, которые более подробно рассматриваются?

EDIT: Я знаю, что могу использовать связанные ссылки. Это не то, о чем я прошу. Я хочу знать, почему свойства не синтезируются? Есть ли проблема с производительностью или проблема безопасности, если компилятор их синтезирует? Если есть, я хочу знать, что и как?

ответ

2

Почему разрешено объявлять свойства в категориях [...]?

Свойства имеют много аспектов (во время компиляции и выполнения).

  1. Они всегда объявляют один или два метода доступа к классу.
  2. Они могут изменять селектор, когда компилятор преобразует точечную нотацию в сообщения.
  3. В сочетании с директивой @synthesize (или по умолчанию) они могут заставить компилятор синтезировать методы доступа и, возможно, ivars.
  4. Они добавляют информацию интроспекции классу, доступному во время выполнения.

Большинство из этих аспектов по-прежнему полезны, когда объявления свойств в категориях (или протоколах) и синтезе недоступны.

Является ли категоризация чисто техникой компилятора?

№ Категории, как свойства, имеют как время компиляции, так и аспекты выполнения.

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

2

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

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

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

Таким образом, свойство в категории имеет смысл, если вы используете его необычным абстрактным способом, а @synthesize - это облегчить общий путь.

+0

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

+0

@iRaviiVooda Вот что говорит Маттиас: вы можете использовать свойства в категориях, но вы не можете их синтезировать. –

+0

Я считаю, что он говорит не о том, чтобы рассматривать свойство как систему хранения данных, а как функциональность. Но функциональность, то есть геттеры и сеттеры, также не объявлены. Это противоречит его заявлению. –

0

Возможно, вы захотите ознакомиться с NSHipster о том, как реализовать хранение объектов в категориях.

Цитата из статьи: «Почему это полезно? Это позволяет разработчикам добавлять пользовательские свойства к существующим классам в категории, что является другим значимым недостатком для Objective-C».

+0

Я знаю, что могу использовать связанные ссылки. Это не то, о чем я прошу. Я хочу знать, почему свойства не синтезируются? Есть ли проблема с производительностью или проблема безопасности, если компилятор их синтезирует? Если есть, я хочу знать, что и как? –

0

@synthesize информирует компилятор, чтобы обеспечить реализацию по умолчанию для сеттера и получателя.

Упомянутые установщики/получатели по умолчанию полагаются на существование какого-либо хранилища внутри объекта.

Категории не предоставляют дополнительное хранение, поэтому установщики/получатели по умолчанию не имели бы место для хранения или чтения.

Альтернатива заключается в использовании:

@dynamic

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

Один из способов - использовать связанные объекты. Другим было бы хранение/чтение из совершенно несвязанного места, например, доступного словаря NSUserDefaults или ...

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

Смежные вопросы