2010-02-02 22 views
8

¿Es posible crear una clase sin método init para forzar a todos los llamantes a crear el objeto con un método de fábrica?Crear una clase sin método init (Objective-c)

+1

Puede ser útil explicar lo que realmente quiere lograr. – Chuck

+1

Parece ser una pregunta perfectamente legítima para mí, que no necesita contexto para tener sentido. Hay muchas razones por las cuales tendría una clase que no necesitaría ninguna configuración específica. –

+0

@Squeegy: Chuck tenía razón: la pregunta original debería haber explicado lo que quería lograr. De las respuestas a continuación, está claro que algunos de los que respondieron no estaban seguros de lo que estaba preguntando (de hecho, supervoto el comentario de Chuck) – Casebash

Respuesta

5

Así que, básicamente, quiere asegurarse de que su clase nunca se inicie con -init, ¿verdad? No puede hacer exactamente lo que quiere hacer, pero puede acercarse.

Dado que heredas de NSObject, tienes un método init y no hay nada que puedas hacer para evitar que se llame.Dicho esto, se podía anular init para esto:

- (id)init 
{ 
    [self dealloc]; 
    @throw [NSException exceptionWithName:@"MyExceptionName" reason:@"Reason" userInfo:nil]; 
    return nil; 
} 

De esta manera, cada vez que alguien llama a su método init, que mata el objeto, por lo que en términos prácticos, el método init es más o menos un-exigible.

+0

¿Object-c tiene algo así como una excepción no implementada? – Casebash

+0

En realidad no necesita el retorno al final; nunca se alcanzará – Casebash

+1

Objective-C es una excepción, poco amigable, ya que puede hacer que los objetos se filtren por todas partes (ya que sus llamadas de 'liberación' nunca se pueden alcanzar) . Si no usas el tiempo de ejecución recolectado como basura, por triste que pueda sonar, es mejor que simplemente no los uses. – zneak

0

Sure. En Objective-C, no hay constructores reales. init -los métodos de tipo se utilizan generalmente para inicializar una clase, en la misma línea que un constructor, pero son solo un método "normal" (no hay nada especial acerca de ellos como los hay, por ejemplo, los constructores de Java).

Dicho esto, a menos que su clase hace sin inicialización de sus casos, es probable que desee a tener algún tipo de init método.

0

NSObject implementa un método init para usted que hace lo que hace. Si su clase no tiene nada que configurar cuando se crea una instancia, simplemente no anule el método -(id)init provisto por NSObject. Pero aún lo llamas cuando creas la instancia.

1

Depende. Si su clase hereda de NSObject, tendrá el método heredado init (que no hace nada con sus variables de instancia). Entonces, en ese sentido, incluso si realmente no quisiera tener un método init, probablemente aún tenga uno. Entonces, si su pregunta era "¿Debo implementar un método trivial init?", La respuesta es "no, no es necesario". Sin embargo, si su pregunta era "¿Tengo que llamar al método init si no lo anulé?", La respuesta es "sí, lo hace". Hagas lo que hagas con las subclases de NSObject, en algún momento aún debes llamar al init después de que se crea el objeto. Tal es la forma de vida.

Dicho esto, que lo más probable desea un método init, a menos que su inicialización de objetos requiere nada más que la reducción a cero toda su objeto.

De lo contrario, si decide no Heredar del NSObject o cualquiera de sus subclases y simplemente hereda de nada, lo cual es claramente una mala idea debido a cómo los NSObject clase aborda todo lo que el tiempo de ejecución ObjC tiene que hacer y el los requisitos son bastante altos, entonces posiblemente terminará sin el método initen total. Pero en serio, no intentes esto en casa.

4

Si realmente quería causar problemas para los usuarios de su clase que utilizan init, que puede hacer:

@implementation MyClass 

- (id) init 
{ 
    // Still have to make sure the runtime has initialised everything for "self" 
    self = [super init]; 
    if (!self) return nil; 
    [self release]; // some say you should use [super dealloc] 
    [super doesNotRecognizeSelector:_cmd]; 
    return nil; 
} 

@end 

se invoca super 's doesNotRecognizeSelector: porque es posible que desee poner en práctica su propio comportamiento para los selectores no reconocidos para Tu clase.

+0

¿Por qué no podemos simplemente devolver nada? – Casebash

+0

Oh, sí, si ha sido asignado deberíamos lanzar – Casebash

+0

Puedes simplemente devolver cero, y esa es probablemente la mejor opción aquí. – Chuck

Cuestiones relacionadas