Изначально классы 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
.
Конечным результатом является то, что ваши ивары могут быть полностью приватными, и вы можете менять их по своему усмотрению, без необходимости перекомпиляции подклассов.