В Objective-C, раздел @interface перечисляет переменные экземпляра ... разве это не неправильно? - PullRequest
5 голосов
/ 24 июня 2011

Предположительно, интерфейс должен говорить об Абстракции - Интерфейсе класса - какие методы доступны, и какие аргументы они принимают, и каковы возвращаемые значения - так что переменные экземпляра определяются в @раздел интерфейса может быть немного запутанным?

Эти переменные экземпляра могут быть чем угодно, и они являются внутренними деталями реализации - программист может определить class A, используя 10 переменных экземпляра, а другой программист может переписать весь классс тем же интерфейсом (API) и использованием только 6 переменных экземпляра, поэтому переменные экземпляра действительно не имеют отношения к разделу @interface, не так ли?

Было бы более разумно, если бы переменные экземпляраперечислены в отдельном разделе, таком как @states, чтобы указать, что они являются внутренними состояниями объекта?

Ответы [ 2 ]

5 голосов
/ 24 июня 2011

Изначально классы Objective-C были немного больше, чем структуры внутри структур. То есть скажем, у вас есть подкласс NSObject и подкласс этого подкласса. Компилятор будет эффективно объединять ivars для создания структуры, которая могла бы инкапсулировать ivars для всего экземпляра.

* 1003 Т.е. *

{{{
  // @interface NSObject
  Class isa;
  }
 // @interface Subclass : NSObject
 int ivar1;
 int ivar2;
 }
// SubSubclass : Subclass
int ivar3;
}

Таким образом, ивари должны были быть выставлены так, чтобы компилятор мог вычислить правильные смещения для различных иваров в подклассах, и, как вы заметили, то, что должно было быть деталью реализации, стало частью открытого API класса.

т.е. это проблема «хрупкого базового класса». Вы не можете изменить ivars в суперклассе, не перекомпилировав все подклассы, известные и неизвестные, иначе вы рискуете потерпеть крах.

Все это было исправлено в "современном ABI", который шел вместе с Objective-C 2.0, более или менее (это было не на всех платформах из-за зависимостей двоичной совместимости).

Исправив проблему «хрупкого базового класса», он также освободил компилятор для принятия объявлений ivar за пределами @interface, в том числе в @implementation, как часть расширения класса или объявления, подразумеваемого @synthesize.

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

1 голос
/ 24 июня 2011

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

Кроме того, если вы не хотите показывать фактическую переменную экземпляра, а только свойства-аксессоры, вы можете просто определить@property в интерфейсе и в реализации (не поле экземпляра) используйте @synthesize myProperty = _myField;.Все там.

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