2010-12-27 10 views
7

Tengo dos métodos diferentes para inicializar mi clase objetivo-c. Uno es el predeterminado, y uno toma un parámetro de configuración. Ahora, soy bastante verde en lo que respecta al objetivo-c, pero he implementado estos métodos y me pregunto si hay una forma mejor (más correcta/de buen estilo) para manejar la inicialización que la forma en que lo hice . Es decir, ¿escribí estas funciones de inicialización de acuerdo con los estándares y el buen estilo? Simplemente no se siente bien comprobar la existencia de selfPtr y luego regresar en función de eso.objetivo-c método init predeterminado para la clase?

A continuación se encuentran mi encabezado de clase y los archivos de implementación. Además, si detecta cualquier otra cosa que sea incorrecta o malvada, por favor hágamelo saber. Soy un desarrollador de C++/Javascript que está aprendiendo objetivo-c como hobby y agradecería cualquier consejo que pueda ofrecer.

#import <Cocoa/Cocoa.h> 

// class for raising events and parsing returned directives 

@interface awesome : NSObject { 
// silence is golden. Actually properties are golden. Hence this emptiness. 
} 

// properties 
@property (retain) SBJsonParser* parser; 
@property (retain) NSString* eventDomain; 
@property (retain) NSString* appid 

// constructors 
-(id) init; 
-(id) initWithAppId:(id) input; 

// destructor 
-(void) dealloc; 


@end 

#import "awesome.h" 
#import "JSON.h" 


@implementation awesome 



- (id) init { 
if (self = [super init]) { 
    // if init is called directly, just pass nil to AppId contructor variant 
    id selfPtr = [self initWithAppId:nil]; 
} 

if (selfPtr) { 
    return selfPtr; 
} else { 
    return self; 
} 
} 

- (id) initWithAppId:(id) input { 
if (self = [super init]) { 
    if (input = nil) { 
    input = [[NSString alloc] initWithString:@"a369x123"]; 
    } 
    [self setAppid:input]; 
    [self setEventDomain:[[NSString alloc] initWithString:@"desktop"]]; 
} 
return self; 
} 

// property synthesis 
@synthesize parser; 
@synthesize appid; 
@synthesize eventDomain; 

// destructor 
- (void) dealloc { 
self.parser = nil; 
self.appid = nil; 
self.eventDomain = nil; 
[super dealloc]; 
} 

@end 

Gracias!

+1

Un problema particular que veo es que si se usa 'init', entonces' [super init] 'se llama dos veces. – dreamlax

+2

También está filtrando la propiedad 'eventDomain', porque crea un objeto con un recuento de propiedad +1 y lo asigna a un método que aumenta el recuento de propiedad a +2, su método dealloc solo lo vuelve a bajar a +1.Debería ser 0 en relación con su objeto 'impresionante'. – dreamlax

+0

Además, el 'Cocoa/Cocoa.h' incluido es para Mac OS X, no para iOS. – jer

Respuesta

14

Cuando uno inicializador simplemente realiza la más compleja inicializador con algunos parámetros por defecto, lo llaman como tal:

-(id)init { 
    return [self initWithAppID:nil]; 
} 

-(id)initWithAppID:(id)input { 
    if (self = [super init]) { 
    /* perform your post-initialization logic here */ 
    } 
    return self; 
} 

Por lo general, intente hacer que uno de los inicializadores sea el "inicializador designado", lo que significa que es el que siempre se invoca. En este caso, eso es -initWithAppID:.

0

Para ser sincero, veo esto como un punto discutible. Su segundo método de inicialización no tiene sentido cuando recibe un argumento nulo (además tiene un problema lógico en su comprobación condicional si la entrada es nula). Lo que haría en este caso, es proporcionar un método de inicialización, y dos métodos de clase de fábrica que actúan de la manera habitual: devolver instancias autorreleasadas, y en una de ellas, proporcionar su valor predeterminado.

Por ejemplo, declarar un método de clase:

+ (awesome*)awesome; 
+ (awesome*)awesomeWithAppId:(id)foo; 

y en su aplicación para +awesome por ejemplo, escribir así:

+ (awesome*)awesome 
{ 
    return [[[awesome alloc] initWithAppId:@"a369x123"] autorelease]; 
} 

Y del mismo modo, en su awesomeWithAppId: algo como esto:

+ (awesome*)awesomeWithAppId:(id)foo 
{ 
    return [[[awesome alloc] initWithAppId:foo] autorelease]; 
} 

Por otra parte, esto puede ser solo yo.

0

El default será lo que uno decide llamar,

[awesome alloc] init]; 
[awesome alloc] initWithAppId:ID]; 
1

Su método init debe llamar al inicializador preferido, initWithAppId :, en lugar de la súper implementación. Entonces el initWithAppId llama a la súper implementación, como lo hace. Además, en initWithAppId :, tiene if (input = nil), que siempre establecerá input en cero y evaluará a YES. Aquí están las implementaciones adecuadas.

- (id)init { 
    return [self initWithAppId:nil]; 
} 
- (id)initWithAppId:(id)input { 
    if((self = [super init])) { 
     if(input == nil) input = @"a369x123"; 
     self.appid = input; 
     self.eventDomain = @"desktop"; 
    } 
    return self; 
} 
Cuestiones relacionadas