2012-01-21 15 views
16

Teniendo en cuenta esto:Cómo crear una instancia de una clase en Objective-C que no heredan de NSObject

Person.h:

@interface Person 
{ 
} 
- (void) sayHello; 
@end 

Person.m:

#import "Person.h" 

@implementation Person 

- (void)sayHello 
{ 
    printf("%s", "Steve"); 
} 

@end 

Cómo hacer usted crea una instancia de la Persona? He intentado esto:

Person *p = [Person new]; 

eso no funciona, ni esto:

Person *p = [Person alloc]; 

[ACTUALIZACIÓN]

me olvidaba decirte, yo ya probé heredando de NSObject, el nuevo y alloc trabajos. Solo tengo curiosidad si podemos instanciar una clase que no hereda de NSObject.

+8

¿Qué le pasa a 'Persona' que hereda de' NSObject'? – Costique

+0

+1 ya que esta es una pregunta muy interesante, aunque el valor práctico podría ser muy poco. – vikingosegundo

+0

@Costique: Nada, es solo que hay muchos tutoriales que encontré en la web que no mencionaron que es un requisito (es decir, heredar de NSObject). ejemplo: http://en.wikibooks.org/wiki/Objective-C_Programming/syntax Intentó heredar de Object, pero '[Person new]' tampoco funciona – Hao

Respuesta

28

Usted absolutamente puede hacerlo. Su clase simplemente necesita implementar +alloc en sí, de la forma en que lo hace NSObject. En la base, esto solo significa usar malloc() para tomar un trozo de memoria lo suficientemente grande como para adaptarse a la estructura que define una instancia de su clase.

La administración de memoria con recuento de referencias también sería agradable (retain/release); esto es en realidad parte de NSObjectprotocol. Puede adoptar el protocolo e implementar estos métodos también.

Como referencia, se puede ver en the Object class, que es una raíz de clase ObjC como NSObject, que Apple ofrece en su repositorio de código abierto para el tiempo de ejecución de Objective-C:

@implementation Object 

// Snip... 

+ alloc 
{ 
    return (*_zoneAlloc)((Class)self, 0, malloc_default_zone()); 
} 

// ... 

- init 
{ 
    return self; 
} 

// And so on... 

Dicho esto, usted debe piense en NSObject como una parte integral del tiempo de ejecución de ObjC. Hay poco o ningún motivo para implementar su propia clase de raíz fuera de la curiosidad, la investigación o la experimentación (que, sin embargo, no debe desalentarse en absoluto).

+5

+1 esta es la respuesta correcta. Realmente, el * único * momento en el que no desea heredar de 'NSObject' es cuando va a hacer algo * fundamentalmente diferente * en términos de gestión de memoria. –

+0

Una respuesta profunda con respecto al objetivo-c que va más allá: "Haga clic en el botón brillante en XCode" ... ¡Impresionante! +1 –

+0

¿Esta respuesta también se aplica para rápido? – user3797599

-6

no se puede ..

Alloc y nueva ..copy init todos estos métodos se definen en NSObject ..

No se puede también crear su propio puesto de manzana no lo hace proporcionar la clase de implementación NSObject ... así que debe heredar de NSObject o su subclase para que pueda inicializar su clase

+2

por supuesto es posible. Apple también lo hizo. usted "solo" tiene que hacer su propia gestión de memoria estilo C. NSObject no forma parte del lenguaje Objective-C, ya que no es Foundation, UIKit, AppKit, ... – vikingosegundo

+1

No entiendo por qué no ha eliminado esta respuesta cuando es tan claramente incorrecta. ¡Gane una insignia de Presión de compañeros! :) –

4

Debe:

  1. Heredar del NSObject,
  2. Hacer una clase "pobre" con sus propios mallocs, etc, o
  3. uso de Objective-C++ y crear una clase de C++.

Por supuesto, ninguno de los otros dos encajan en la administración de almacenamiento de Objective-C, y sus protocolos de llamada, etc. son diferentes.

+2

¡Casi! Para 2, simplemente puede implementar + alloc, -retain, -release, etc ... en términos de malloc y su propio refcount. Al implementar el protocolo NSObject *, puede participar de forma bastante transparente. –

+0

-1 usted no * tiene * para heredar de 'NSObject'. Hay muchas clases que no, como 'NSProxy'. –

+1

@DaveDeLong él significa que debe * cualquiera * hacer 1. * o * 2. * o * 3. –

3

Existe (muy probablemente) una buena razón para no querer heredar de NSObject, pero hay muchas buenas razones para hacerlo.

Me gustaría saber por qué no desea heredar de NSObject. Supongo que se debe a una falta de conocimiento más que a una necesidad real.

Pero incluso sin saber esa razón: No lo hagas. Es tan difícil hacer esto bien de una manera que todavía funciona bien con otras clases de Objective-C como para ser virtualmente imposible.

De todos modos, estás instanciando tus objetos de una manera que oculta lo que realmente se hace.Mientras que en Java, por lo general, crear instancias a través del método constructor por defecto new, en Objective-C se ejemplariza llamando alloc en la clase y luego init en la instancia:

Person *aPerson = [[Person alloc] init]; 

(Es posible de usar Simplemente Person new, pero yo no lo haría porque oculta lo que realmente se hace de usted)

Implementa su clase de modo que herede de NSObject y luego, si es necesario, escriba su propio método init.

Si desea conectarse a la consola, utilice NSLog:

NSLog(@"Hello %@", @"Steven"); 

(@"" es un constructor especial para un NSString Cuerdas en Objective-C no son matrices de bytes, pero los objetos..)

+3

Por supuesto, en Objective-C 'new' es solo una abreviatura de vanilla' alloc/init'. –

Cuestiones relacionadas