Почему подкласс NSObject?
Какова цель/использование NSObject в Objective-C? Я вижу классы, которые расширяют NSObject следующим образом:
@interface Fraction : NSObject
В С++ или Java мы не используем какие-либо переменные, такие как NSObject, даже если у нас есть директивы препроцессора и инструкции импорта как в Objective-C, так и в Java.
Почему классы явно наследуются от NSObject в Objective-C? Каковы последствия не объявления наследования из NSObject?
Ответы
Ответ 1
Мы используем NSObject для явного указания того, что наследует данный класс. Я не уверен в С++, но в Java есть нечто похожее - класс Object. Единственное различие заключается в том, что Java не требует, чтобы классы явно спускались с Object - язык предполагает все, что не имеет указанного родительского класса, спускается из Object. Objective-C отличается тем, что позволяет определять разные корневые классы - вам разрешено создавать класс, который не наследуется от NSObject.
Примером такого другого корневого класса является NSProxy
.
Посмотрите на источник GNUstep NSObject, он показывает, как методы взаимодействуют с Objective-C с помощью функций C.
+ (id) allocWithZone:(NSZone*)z
{
return NSAllocateObject(self, 0, z);
}
- (void) dealloc
{
NSDeallocateObject (self);
}
+ (BOOL) isSubclassOfClass: (Class)aClass
{
return GSObjCIsKindOf(self, aClass);
}
Ответ 2
Так как объектно-ориентированные языки имеют понятие наследования, в любой иерархии наследования есть корневой класс. В Java родительский класс по умолчанию (если он не указан) java.lang.Object
, тогда как в Objective-C, если вы явно не объявляете родительский класс, вы его не получите. По сути, ваш класс становится самим корневым классом. Это распространенная ошибка среди новичков Objective-C, поскольку вы обычно хотите наследовать от NSObject в таких случаях.
Хотя это часто проблематично и озадачивает, это фактически позволяет довольно гибко, так как вы можете определить свои собственные иерархии классов, которые действуют совершенно иначе, чем NSObject. (Java не позволяет вам делать это вообще.) С другой стороны, если вы не знаете, что делаете, легко попасть в проблему таким образом. К счастью, компилятор предоставит предупреждения, если вы вызываете метод, не определенный классом без объявленного родительского класса, например, который вы обычно ожидаете наследовать от NSObject.
Что касается "использования" NSObject, проверьте документацию класс NSObject и протокол NSObject. Они определяют общие методы, используемые для распределения объектов, управления памятью, сравнения, хэширования, описания печати, проверки членства в классе, запроса того, реагируют ли объекты на селектор и т.д. В принципе, NSObject "хорош для" предоставления основных функций объектов Objective-C бесплатно.
Ответ 3
Все классы не обязательно наследуются от NSObject, но это ядро для многих классов, потому что оно обеспечивает такие функции, как alloc, сохранение и выпуск.
Ответ 4
NSObject - это корневой класс всех классов. По моей оценке, 3 основные функции - выделить и инициализировать память для вас (alloc и init), а также предоставить функцию описания.
Objective-C - все об объектах, отправляющих сообщения другим объектам - поэтому существует NSObject, чтобы обеспечить эту базовую функциональность.
Если это звучит странно для вас, вы можете больше узнать о парадигмах программирования, особенно объектно-ориентированном программировании. Однако в двух словах Objective C является простым расширением языка C. C дает вам возможность программировать память, цифры и символы компьютера, но делать что-либо еще (например, использовать строки или показывать виды, например), вам нужна часть расширения, а NSObject - это начало этого расширения.
Это может быть полезным упражнением для выбора класса (например, NSString или любого другого) и следовать за его суперклассами обратно в NSObject, чтобы узнать, какая функциональность каждого класса добавлена.
Надеюсь, что это поможет...