with tutorial framework español djangoproject desde con cero applications objective-c cocoa-touch cocoa oop

objective c - tutorial - Objective-C: ¿Cómo accedes a las propiedades de los padres desde las subclases?



tutorial django (5)

Si tengo esta clase definida, ¿cómo puedo acceder a la propiedad someObject en subclases sin errores de compilación?

@interface MyBaseClass // someObject property not declared here because I want it to be scoped // protected. Only this class instance and subclass instances should be // able to see the someObject property. @end // This is a private interface extension...properties declared here // won''t be visible to subclasses. However, I don''t see any way to // declare protected properties... @interface MyBaseClass (private) @property (nonatomic, readwrite, retain) NSObject *someObject; @end

@interface MySubclass : MyBaseClass @end @implementation MySubclass - (id) init { // Try to do something with the super classes'' someObject property. // Always throws compile errors. // Semantic Issue: Property ''someObject'' not found // object of type ''MySubclass *'' self.someObject = nil; } @end



Obviamente no entiendo cómo funciona la herencia en Objective-c. ¿Alguien podría iluminarme?


A juzgar por el () después del nombre de su clase base, parece que está declarando una extensión de interfaz privada dentro de la implementación de su clase, ¿es este el caso? De ser así, la variable solo será accesible desde esa implementación de clase.

¿Su MyBaseClass hereda de NSObject directamente?

Si es así, debe declarar la propiedad someObject en su archivo de interfaz, como en:

@interface MyBaseClass : NSObject { } @property (nonatomic, retain) NSObject *someObject;

Y luego sintetízala como si ya estuvieras haciendo.


Esta es una alternativa que cumple con la mayoría de los objetivos.

En tu encabezado, define la interfaz

@interface MyBaseClass : NSObject { NSObject *inheritableObject; } @property (readonly) NSObject *inheritableObject;

Ahora puede editar el objeto heredableObject en MyBaseClass, así como en cualquier clase que herede de MyBaseClass. Sin embargo, desde el exterior, es de solo lectura. No es privado como en el caso de @interface MyBaseClass (), pero está protegido contra cambios no controlados.


La solución que busca es declarar la propiedad privada MyBaseClass en una extensión de clase:

@interface MyBaseClass () @property (nonatomic, readwrite, retain) NSObject *someObject; @end

Entonces puede hacer esa declaración tanto en MyBaseClass como en MySubclass. Esto le permite a MySubclass conocer estas propiedades para que su código pueda hablar de ellas.

Si la repetición le molesta, coloque la extensión de clase en un archivo .h propio e impórtelo en ambos archivos .m.

Daré un ejemplo de mi propio código. Aquí está MyDownloaderPrivateProperties.h :

@interface MyDownloader () @property (nonatomic, strong, readwrite) NSURLConnection* connection; @property (nonatomic, copy, readwrite) NSURLRequest* request; @property (nonatomic, strong, readwrite) NSMutableData* mutableReceivedData; @end

No hay un archivo .m correspondiente y eso es todo lo que hay en este archivo; es, por así decirlo, puramente declarativo. Ahora aquí está el inicio de MyDownloader.m :

#import "MyDownloader.h" #import "MyDownloaderPrivateProperties.h" @implementation MyDownloader @synthesize connection=_connection; @synthesize request=_request; @synthesize mutableReceivedData=_mutableReceivedData; // ...

Y aquí está el comienzo de su subclase MyImageDownloader.m :

#import "MyImageDownloader.h" #import "MyDownloaderPrivateProperties.h"

Problema resuelto. La privacidad se conserva, ya que estas son las únicas clases que importan MyDownloaderPrivateProperties.h, por lo que son las únicas clases que conocen estas propiedades en lo que respecta al compilador (y esa es toda esa privacidad en Objective-C). La subclase puede acceder a las propiedades privadas cuyos accesores son sintetizados por la superclase. Creo que eso es lo que querías lograr en primer lugar.


así es como accedes a ellos. cómo los declaras es lo que te está mordiendo:

@interface MyBaseClass : NSObject @property (nonatomic, readwrite, retain) NSObject *someObject; @end

esta es la forma normal de declarar una nueva clase objc.

al agregar los paréntesis (en lugar de declarar la superclase - NSObject en este caso), ha declarado una extensión de clase, que probablemente no sea visible para la subclase (a través de la inclusión).

probablemente nunca necesites declarar una clase raíz en objc:

@interface MyBaseClass // << superclass omitted @property (nonatomic, readwrite, retain) NSObject *someObject; @end

NSObject (o una subclase de, suponiendo que sea el sistema de apple de destino) debe ser la clase base a menos que tenga mucha experiencia y sepa para qué es una clase de raíz.

las extensiones de clase a menudo se usan para ''simular'' interfaces privadas. mediante simulación, el compilador no aplica esto, ya que se aplicaría en otros idiomas. por ejemplo, todos los mensajes siguen siendo dinámicos, aunque la subclase puede (sin saberlo) anular los métodos en sus extensiones, si se declara con el mismo selector.


super.someObject = nil; . La herencia significa que MyBaseClass es su súper clase.