2009-02-18 11 views
46

In Objective-C 2.0, è possibile creare un metodo in cui l'argomento è facoltativo? Cioè, si può avere una chiamata di metodo come questo:Argomenti facoltativi in ​​Objective-C 2.0?

[aFraction print]; 

così come questo:

[aFraction print: someParameter]; 

nello stesso programma.

Apple linguaggio di programmazione Objective-C 2.0 guida contrasti Obj-C con Python e sembra dire che questo non è consentito. Sto ancora imparando e voglio esserne sicuro. Se è possibile, allora qual è la sintassi, perché il mio secondo esempio di codice non funziona.

Aggiornamento: OK, ho appena fatto due metodi, entrambi denominati "stampa".

intestazione

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

attuazione

-(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"); 
    } 
} 

le linee di programma interessati

... 
    printParamFlag = TRUE; 

// no parameter 
    [aCodeHolder print]; 

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

Non posso BEL credo che abbia funzionato C'è qualche ragione per cui non dovrei farlo?

+0

Credo che ciò che non è permesso è riordinare gli argomenti quando si usano i nomi. – user57368

+0

Avere sia la stampa che la stampa: non aiuta la leggibilità. –

+2

Funziona, perché i due punti fanno parte del nome del metodo. – Kornel

risposta

77

È possibile dichiarare diversi metodi:

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

Nella realizzazione si può fare questo:

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

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

Edit:

prega di non utilizzare print e print: allo stesso tempo. Prima di tutto, non indica quale sia il parametro e in secondo luogo nessuno (ab) usa l'Objective-C in questo modo. La maggior parte dei framework ha nomi di metodi molto chiari, questa è una cosa che rende Objective-C così semplice da programmare con. Uno sviluppatore normale non si aspetta questo tipo di metodi.

ci sono nomi migliori, ad esempio:

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

quando passo nil come argomento, ricevo un avvertimento: "passare l'argomento 1 di 'print:' rende intero da puntatore senza cast". Dovrei semplicemente ignorarlo? – willc2

+0

Potresti pubblicare la riga dove si verifica questo errore? Non sono sicuro di cosa stai facendo. Questo errore non dovrebbe accadere. –

+0

è possibile utilizzare NIL se il tipo di parametro è (id). Nel mio codice il tipo di parametro era (BOOL). La soluzione era di cambiare NIL a 0 poiché questo è il tipo previsto. Lo capisco adesso. La cosa multipla dei metodi è fantastica. – willc2

15

Il modo in cui l'avete fatto è il modo giusto per farlo in Objective-C. È ampiamente utilizzato nella stessa Cocoa. Per esempio, alcuni di inizializzatori di NSString:

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

Il motivo per cui funziona è perché la : fa parte del nome del metodo, in modo per quanto riguarda il compilatore è interessato, print e print: sono completamente diversi messaggi che non ci sono più strettamente connesso di "stampa" e "sprint".

Tuttavia, i nomi particolari dei metodi che hai fornito non sono un ottimo caso per questo, perché non è chiaro dal nome qual è il parametro (o cosa "print" di per sé significa se il parametro è ciò che l'oggetto stampe). Sarebbe meglio avere, per esempio, printFalseMessage e printMessageWithFlag:.

+1

Heh, era solo il codice di un esercizio di un libro.Ho la religione di descrittivaVariableNamesPinkySwearScoutsHonor = TRUE; Ora che sto lavorando con un IDE corretto, i nomi lunghi non sono grandi. – willc2

5

Leggermente correlati è possibile avere argomenti opzionali. Significa che puoi chiamare un metodo con qualsiasi numero di argomenti, se lo desideri. Ma questa è una caratteristica di C (vararg).

Un esempio, è la NSArray messaggio:

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

Esempio di utilizzo:

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

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

Questo è direttamente dai documenti di Apple. Si indica la fine di tutti i tuoi argomenti con uno nil.

+2

L'utilizzo di questo per rappresentare argomenti facoltativi anziché un elenco di lunghezza variabile per un argomento sarebbe piuttosto perverso. – Chuck

+0

Come dichiarare il tipo di metodo? – youshunei

+0

+ (id) arrayWithObjects: parametri (NSArray *); <= come questo? – youshunei

7

Un'altra opzione per più argomenti opzionali è quello di passare tutti in un NSDictionary:

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

quindi dichiarare che il dizionario opzioni può contenere:

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

si può quindi consentire uno qualsiasi dei tasti essere assente e persino il dizionario stesso potrebbe essere zero.

+2

Questo è molto comune in Ruby. Creare un dizionario è un po 'prolisso in ObjC-Cocoa, quindi è generalmente meglio salvare questo per grandi serie di opzioni correlate piuttosto che usarlo come "scorciatoia" per passare argomenti: sarebbe più simile a una rotta panoramica. Perderai anche il controllo dei caratteri. – Chuck

+0

Penso che Apple lo usi anche per alcuni metodi, come nelle stringhe. –

1

Per evitare la Parse problema: 'avariable' usato come il nome del parametro precedente piuttosto che come parte del selettore si ottiene dal compilatore come un avvertimento che si dovrebbe fare:

- (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"); 
    } 
} 

e si potrebbe chiamare il metodo, ad esempio:

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

o

[self printWithParameter:YES color:[UIColor someColor]] // YES instead of 1 
Problemi correlati