2009-02-18 18 views
46

En Objective-C 2.0, ¿es posible hacer un método donde el argumento sea opcional? Es decir, se puede tener una llamada a un método como éste:Argumentos opcionales en Objective-C 2.0?

[aFraction print]; 

, así como este:

[aFraction print: someParameter]; 

en el mismo programa.

Apple Objective-C 2.0 Programming Language guía contrasta Obj-C con Python y parece decir que esto no está permitido. Todavía estoy aprendiendo y quiero estar seguro. Si es es posible, entonces ¿cuál es la sintaxis, porque mi segundo ejemplo de código no funciona.

Actualización: Bien, acabo de hacer dos métodos, ambos denominados "imprimir".

cabecera

-(void) print; 
-(void) print: (BOOL) someSetting; 

aplicación

-(void) print { 
    [self print:0]; 
} 

-(void) print: (BOOL) someSetting { 
    BOOL sv; 
    sv = someSetting; 

    if (sv) { 
     NSLog(@"cool stuff turned on"); 
    } 
    else { 
     NSLog(@"cool stuff turned off"); 
    } 
} 

las líneas de programa pertinentes

... 
    printParamFlag = TRUE; 

// no parameter 
    [aCodeHolder print]; 

// single parameter 
    [aCodeHolder print:printParamFlag]; 
    ... 

No puedo bel Creo que funcionó. ¿Hay alguna razón por la que no debería hacer esto?

+0

Creo que lo que no está permitido es reordenar los argumentos cuando usas nombres. – user57368

+0

Tener tanto impresión como impresión: no ayuda a la legibilidad. –

+2

Funciona, porque los dos puntos forman parte del nombre del método. – Kornel

Respuesta

77

Se puede declarar varios métodos:

- (void)print; 
- (void)printWithParameter:(id)parameter; 
- (void)printWithParameter:(id)parameter andColor:(NSColor *)color; 

En la aplicación se puede hacer esto:

- (void)print { 
    [self printWithParameter:nil]; 
} 

- (void)printWithParameter:(id)parameter { 
    [self printWithParameter:nil andColor:[NSColor blackColor]]; 
} 

Editar:

Por favor, no use print y print: al mismo hora. En primer lugar, no indica cuál es el parámetro y, en segundo lugar, nadie (ab) usa Objective-C de esta manera. La mayoría de los marcos tienen nombres de método muy claros, esto es lo que hace que Objective-C sea tan fácil de programar. Un desarrollador normal no espera este tipo de métodos.

Hay mejores nombres, por ejemplo:

- (void)printUsingBold:(BOOL)bold; 
- (void)printHavingAllThatCoolStuffTurnedOn:(BOOL)coolStuff; 
+0

cuando paso nil como argumento, aparece una advertencia: "pasar el argumento 1 de 'print:' hace que el entero sea un puntero sin un molde". ¿Debería simplemente ignorarlo? – willc2

+0

¿Podría publicar la línea donde se produce este error? No estoy muy seguro de lo que estás haciendo. Este error no debería suceder. –

+0

puede usar NIL si el tipo de parámetro es (id). En mi código, el tipo de parámetro era (BOOL). La solución fue cambiar NIL a 0 ya que ese es el tipo esperado. Ahora lo entiendo. La cosa de los métodos múltiples es genial. – willc2

15

La forma en que lo hizo es la forma correcta de hacerlo en Objective-C. Se usa ampliamente en Cocoa. Por ejemplo, algunos de los inicializadores de NSString:

– initWithFormat: 
– initWithFormat:arguments: 
– initWithFormat:locale: 
– initWithFormat:locale:arguments: 

La razón funciona es porque el : es parte del nombre del método, así como lo que se refiere al compilador, print y print: son completamente diferentes mensajes que ya no existen estrechamente conectado que "imprimir" y "correr".

Sin embargo, los nombres particulares de los métodos que dio no son muy buenos para esto, porque no está claro por el nombre qué es el parámetro (o qué "impresión" significa si el parámetro es el objeto huellas dactilares). Sería mejor tener, por ejemplo, printFalseMessage y printMessageWithFlag:.

+1

Heh, era solo código de un ejercicio de libro.Tengo la religión de descriptiveVariableNamesPinkySwearScoutsHonor = TRUE; Ahora que estoy trabajando con un IDE apropiado, los nombres largos no son grandes. – willc2

5

Relativamente relacionado puede tener argumentos opcionales. Lo que significa que puede llamar a un método con cualquier cantidad de argumentos si lo desea. Pero esa es una característica de C (varargs).

Un ejemplo, es el mensaje NSArray:

+ (id)arrayWithObjects:(id)firstObj, ... 

Ejemplo de uso:

NSArray *myArray; 
NSDate *aDate = [NSDate distantFuture]; 
NSValue *aValue = [NSNumber numberWithInt:5]; 
NSString *aString = @"a string"; 

myArray = [NSArray arrayWithObjects:aDate, aValue, aString, nil]; 

Esto es directamente de los docs Apple. Usted indica el final de todos sus argumentos con un nil.

+2

Usar eso para representar argumentos opcionales en lugar de una lista de longitud variable para un argumento sería bastante perverso. – Chuck

+0

¿Cómo declarar el tipo de método? – youshunei

+0

+ (id) arrayWithObjects: (NSArray *) params; <= como esto? – youshunei

7

Otra opción para múltiples argumentos opcionales es pasar a todos en un NSDictionary:

- (void)someMethodWithOptions:(NSDictionary *)options; 

declarará que el diccionario opciones puede contener:

- key1, value must be a BlahObject 
- key2, value must be a NonBlahObject 

A continuación, puede permitir que cualquiera de las teclas estar ausente e incluso el diccionario en sí podría ser nulo.

+2

Esto es muy común en Ruby. Sin embargo, crear un diccionario es un poco detallado en ObjC-Cocoa, por lo que generalmente es mejor guardarlo para conjuntos grandes de opciones relacionadas en lugar de usarlo como un "atajo" para pasar argumentos: sería más como una ruta escénica. También pierde la comprobación de tipos. – Chuck

+0

Creo que Apple también lo usa para algunos métodos, como en strings. –

1

para evitar el problema de análisis: 'AVariable' se utiliza como el nombre del parámetro anterior y no como parte del selector se obtiene del compilador como una advertencia que debe hacer:

- (void)printWithParameter:(BOOL)sv color:(NSColor *)color{ 
    // your cool code goes here 
    if (sv) { 
     NSLog(@"cool stuff turned on"); 
    } 
    else { 
     NSLog(@"cool stuff turned off"); 
    } 
} 

y que se podría llamar el método, por ejemplo:

[self printWithParameter:NO color:[UIColor someColor]] // NO instead of 0 

o

[self printWithParameter:YES color:[UIColor someColor]] // YES instead of 1 
Cuestiones relacionadas