objective c - ¿Por qué subclase NSObject?
objective-c inheritance (5)
¿Cuál es el propósito / uso de NSObject en Objective-C? Veo clases que extienden NSObject así:
@interface Fraction : NSObject
En C ++ o Java, no utilizamos ninguna variable como NSObject, aunque tenemos directivas de preprocesador e instrucciones de importación tanto en Objective-C como en Java.
¿Por qué las clases heredan explícitamente de NSObject en Objective-C? ¿Cuáles son las consecuencias de no declarar la herencia de NSObject?
NSObject
La clase raíz de la mayoría de las jerarquías de clases de Objective-C, de las cuales las subclases heredan una interfaz básica para el sistema de tiempo de ejecución y la capacidad de comportarse como objetos Objective-C.
De la documentación de Apple: https://developer.apple.com/documentation/objectivec/nsobject .
Básicamente, la mayoría de los lenguajes de programación OOP explícita o implícitamente especifican la clase base o la funcionalidad base. De lo contrario, no puede construir un sistema donde los objetos se comuniquen entre sí. Las propiedades, la gestión de la memoria y el mecanismo de envío de mensajes son parcial o totalmente proporcionados o soportados por NSObject. Apple proporciona partes de la implementación de Objective-C: https://opensource.apple.com/source/objc4/objc4-723/runtime/NSObject.mm.auto.html , donde es posible ver lo que realmente está dentro de NSObject.
Además, debido a que Objective-C es un lenguaje de la familia C, el compilador y el vinculador deben calcular cómo distribuir el objeto en la memoria y dónde ubicar y encontrar los métodos, eso solo es posible si sabe cómo se encuentra cada una de las clases / instancias en la memoria y dónde. En el caso de Objective-C, todas las clases base (NSObject, NSProxy, etc.) tienen una especificación de eso, por lo que es posible calcular su tamaño y agregar todas las cosas heredadas: https://clang.llvm.org/compatibility.html#objective-c .
En consecuencia el compilador no deja abandonar una clase sin clase base. Por lo tanto, en la clase final, la herencia debe llevar a una de las clases raíz. Aquí está el error que aparece si no lo especificas (de Xcode):
Clase ''ClassWithoutBaseClass'' definida sin especificar una clase base
Dado que los lenguajes orientados a objetos tienen el concepto de herencia, en cualquier jerarquía de herencia hay una clase raíz. En Java, la clase padre predeterminada (si no se proporciona) es java.lang.Object
, mientras que en Objective-C, si no declara explícitamente una clase padre, no obtiene una. Esencialmente, tu clase se convierte en una clase raíz en sí misma. Este es un error común entre los recién llegados a Objective-C, ya que normalmente desea heredar de NSObject en tales casos.
Aunque a menudo es problemático y desconcertante, esto en realidad permite bastante flexibilidad, ya que puede definir sus propias jerarquías de clase que actúan de manera completamente diferente a NSObject. (Java no te permite hacer esto en absoluto). Por otro lado, a menos que sepas lo que estás haciendo, es fácil meterte en problemas de esta manera. Afortunadamente, el compilador proporcionará advertencias si llama a un método no definido por una clase sin una clase padre declarada, como las que normalmente espera heredar de NSObject.
En cuanto al "uso" de NSObject, consulte la documentación de la clase NSObject y el protocolo NSObject . Definen métodos comunes utilizados para la asignación de objetos, la administración de memoria, la comparación, el hash, la impresión de descripciones, la verificación de la pertenencia a la clase, la consulta de si los objetos responden a un selector, etc. gratis.
NSObject es la clase raíz de todas las clases. En mi opinión, las 3 funciones más básicas son asignar e inicializar la memoria para usted (alloc & init), así como proporcionar una función de descripción.
Objective-C tiene que ver con los objetos que envían mensajes a otros objetos, por lo que NSObject existe para proporcionar esa funcionalidad básica.
Si esto le suena extraño, quizás desee leer más sobre los paradigmas de programación, en particular la programación orientada a objetos ... Sin embargo, en pocas palabras, Objective C es una extensión simple del lenguaje C. C le brinda la capacidad de programar la memoria, los números y los caracteres de la computadora, pero hacer cualquier otra cosa (como usar cadenas o mostrar vistas, por ejemplo) necesita la parte de la extensión, y NSObject es el comienzo de esa extensión.
Puede ser un ejercicio útil elegir una clase (como NSString, o cualquiera), y seguir sus superclases de nuevo a NSObject, para ver qué funcionalidad agregó cada clase.
Espero que ayude...
Todas las clases no necesariamente heredan de NSObject pero es el núcleo de muchas de las clases porque proporciona cosas como asignar, retener y liberar.
Usamos NSObject para indicar explícitamente de qué hereda una clase dada. No estoy seguro de C ++, pero en Java hay algo similar: la clase Object. La única diferencia es que Java no requiere que las clases desciendan explícitamente del Objeto: el lenguaje asume que cualquier cosa que no tenga una clase primaria especificada descienda del Objeto. Objective-C es diferente porque le permite definir diferentes clases de raíz: se le permite crear una clase que no hereda de NSObject.
Un ejemplo de una clase raíz diferente es NSProxy
.
Eche un vistazo a la fuente NSObject de GNUstep , muestra cómo los métodos interactúan con el tiempo de ejecución de object -c a través de las funciones C.
+ (id) allocWithZone:(NSZone*)z
{
return NSAllocateObject(self, 0, z);
}
- (void) dealloc
{
NSDeallocateObject (self);
}
+ (BOOL) isSubclassOfClass: (Class)aClass
{
return GSObjCIsKindOf(self, aClass);
}