Зачем нужен подкласс NSObject?

Какова цель / использование NSObject в Objective-C? Я вижу классы, расширяющие NSObject следующим образом:

@interface Fraction : NSObject 

В C ++ или Java мы не используем никаких переменных, таких как NSObject, хотя у нас есть директивы препроцессора и операторы импорта как в Objective-C, так и в Java.

Почему классы явно наследуются от NSObject в Objective-C? Каковы последствия отказа от объявления наследования от NSObject?


person user185590    schedule 19.10.2009    source источник


Ответы (5)


Мы используем NSObject, чтобы явно указать, от чего наследуется данный класс. Я не уверен насчет C ++, но в 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);
}
person Tim    schedule 19.10.2009
comment
На самом деле NSProxy - это другой корневой класс, то есть он не наследуется от NSObject. - person ; 19.10.2009
comment
NSAllocateObject и NSDeallocateObject не относятся к среде выполнения Objective-C. - person ; 07.05.2011
comment
Текущая ссылка для NSProxy: developer.apple.com/reference/foundation/nsproxy - person joan; 14.12.2016

Поскольку объектно-ориентированные языки имеют концепцию наследования, в любой иерархии наследования есть корневой класс. В Java родительский класс по умолчанию (если не указан) - _ 1_, тогда как в Objective-C, если вы явно не объявляете родительский класс, вы его не получите. По сути, ваш класс сам становится корневым. Это распространенная ошибка среди новичков в Objective-C, поскольку в таких случаях вы обычно хотите наследовать от NSObject.

Хотя это часто бывает проблематично и сбивает с толку, на самом деле это дает некоторую гибкость, поскольку вы можете определять свои собственные иерархии классов, которые действуют совершенно иначе, чем NSObject. (Java вообще не позволяет вам этого делать.) С другой стороны, если вы не знаете, что делаете, таким образом легко попасть в неприятности. К счастью, компилятор выдаст предупреждения, если вы вызовете метод, не определенный классом без объявленного родительского класса, например те, которые вы обычно ожидаете унаследовать от NSObject.

Что касается «использования» NSObject, ознакомьтесь с документацией NSObject class и протокол NSObject. Они определяют общие методы, используемые для выделения объектов, управления памятью, сравнения, хеширования, печати описаний, проверки принадлежности к классам, запроса, отвечают ли объекты на селектор и т. Д. В принципе, NSObject «хорош для» обеспечения основных функций объектов Objective-C. бесплатно.

person Quinn Taylor    schedule 19.10.2009

Все классы не обязательно наследуются от NSObject, но это ядро ​​для многих классов, поскольку оно обеспечивает такие вещи, как выделение, сохранение и освобождение.

person ACBurk    schedule 19.10.2009

NSObject - это корневой класс всех классов. По моим оценкам, это 3 основные функции: выделить и инициализировать для вас память (alloc и init), а также предоставить функцию описания.

Objective-C - это объекты, отправляющие сообщения другим объектам, поэтому NSObject существует для обеспечения этой базовой функциональности.

Если это звучит для вас странно, возможно, вы захотите узнать больше о парадигмах программирования, в частности, об объектно-ориентированном программировании ... В двух словах, однако, Objective C - это простое расширение языка C. C дает вам возможность программировать память компьютера, числа и символы, но делать что-либо еще (например, использовать строки или отображать представления), вам нужна часть расширения, а NSObject является началом этого расширения.

Может быть полезным упражнением выбрать класс (например, NSString или любой другой, если на то пошло) и следовать за его суперклассами обратно в NSObject, чтобы увидеть, какие функции добавил каждый класс.

Надеюсь, это поможет...

person user1707891    schedule 20.10.2012

NSObject

Корневой класс большинства иерархий классов Objective-C, от которого подклассы наследуют базовый интерфейс к системе времени выполнения и способность вести себя как объекты Objective-C.

Из документации Apple - https://developer.apple.com/documentation/objectivec/nsobject.

По сути, большинство языков программирования ООП явно или неявно определяют базовый класс или базовую функциональность. В противном случае вы не сможете построить систему, в которой объекты взаимодействуют друг с другом. Свойства, управление памятью, механизм отправки сообщений частично или полностью предоставляются или поддерживаются NSObject. Apple предоставляет части реализации Objective-C - https://opensource.apple.com/source/objc4/objc4-723/runtime/NSObject.mm.auto.html, где можно увидеть, что на самом деле находится внутри NSObject.

Кроме того, поскольку Objective-C - это язык из семейства C, поэтому компилятору и компоновщику необходимо вычислить, как размещать объект в памяти и где размещать и искать методы, это возможно только в том случае, если вы знаете, как каждый из классов / экземпляров находится в памяти и где. В случае Objective-C все базовые классы (NSObject, NSProxy и т. Д.) Имеют спецификацию этого, поэтому можно рассчитать их размер и добавить поверх всего унаследованного материала - https://clang.llvm.org/compatibility.html#objective-c.

Следовательно, компилятор не позволяет оставить класс без базового класса. Итак, в конце наследование классов должно привести к одному из корневых классов. Вот ошибка, которая появляется, если вы не укажете ее (из Xcode):

Класс ClassWithoutBaseClass определен без указания базового класса

person skyylex    schedule 27.04.2018