2009-02-18 8 views
46

En Objective-C 2.0, est-il possible de faire une méthode où l'argument est optionnel? Autrement dit, vous pouvez avoir un appel de méthode comme ceci:Arguments optionnels dans Objective-C 2.0?

[aFraction print]; 

ainsi que ceci:

[aFraction print: someParameter]; 

dans le même programme.

Apple Le langage de programmation Objective-C 2.0 compare Obj-C avec Python et semble dire que cela n'est pas autorisé. J'apprends encore et je veux être sûr. Si est possible, alors quelle est la syntaxe, parce que mon deuxième exemple de code ne fonctionne pas.

Mise à jour: OK, je viens de faire deux méthodes, toutes deux nommées "print".

tête

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

mise en œuvre

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

les lignes de programme pertinentes

... 
    printParamFlag = TRUE; 

// no parameter 
    [aCodeHolder print]; 

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

Je ne peux pas bel ieve ça a marché. Y a-t-il une raison pour laquelle je ne devrais pas faire ça?

+0

Je crois que ce qui n'est pas autorisé est de réorganiser les arguments lorsque vous utilisez des noms. – user57368

+0

Avoir à la fois imprimer et imprimer: n'aide pas la lisibilité. –

+2

Cela fonctionne, car les deux-points font partie du nom de la méthode. – Kornel

Répondre

77

Vous pouvez déclarer plusieurs méthodes:

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

Dans la mise en œuvre, vous pouvez le faire:

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

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

Edit:

S'il vous plaît ne pas utiliser print et print: au même temps. Tout d'abord, il n'indique pas quel est le paramètre et d'autre part, personne (ab) n'utilise Objective-C de cette façon. La plupart des frameworks ont des noms de méthodes très clairs, c'est une chose qui rend Objective-C si facile à programmer. Un développeur normal ne s'attend pas à ce genre de méthodes.

Il y a de meilleurs noms, par exemple:

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

quand je passe nil comme un argument, j'obtiens un avertissement: "passant l'argument 1 de 'print:' rend entier de pointeur sans un cast". Devrais-je l'ignorer? – willc2

+0

Pourriez-vous poster la ligne où cette erreur se produit? Je ne suis pas vraiment sûr de ce que tu fais. Cette erreur ne devrait pas arriver. –

+0

vous pouvez utiliser NIL si le type de paramètre est (id). Dans mon code, le type de paramètre était (BOOL). La solution était de changer NIL à 0 puisque c'est le type attendu. Je comprends maintenant. La chose des méthodes multiples est géniale. – willc2

15

La façon dont vous l'avez fait est la bonne façon de le faire en Objective-C. Il est largement utilisé dans le cacao lui-même. Par exemple, certains des initialiseurs de NSString:

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

La raison pour laquelle cela fonctionne est parce que la : fait partie du nom de la méthode, donc autant que le compilateur est concerné, print et print: sont des messages complètement différents qui ne sont plus étroitement connecté que "print" et "sprint".Cependant, les noms particuliers des méthodes que vous avez donnés ne sont pas très bons pour cela, car le nom ne précise pas ce qu'est le paramètre (ou ce que "imprimer" signifie par lui-même si le paramètre est quel est l'objet). impressions). Il vaudrait mieux avoir, disons, printFalseMessage et printMessageWithFlag:.

+1

Heh, c'était juste du code d'un exercice de livre.J'ai la religion de descriptiveVariableNamesPinkySwearScoutsHonor = TRUE; Maintenant que je travaille avec un bon IDE, les noms longs ne sont pas grands. – willc2

5

Légèrement liés, vous pouvez avoir des arguments optionnels. Cela signifie que vous pouvez appeler une méthode avec n'importe quel nombre d'arguments si vous le souhaitez. Mais c'est une fonctionnalité de C (varargs).

Un exemple, est le NSArray message:

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

Exemple d'utilisation:

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

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

Ceci est directement à partir de la documentation Apple. Vous indiquez la fin de tous vos arguments avec nul.

+2

Utiliser cela pour représenter des arguments optionnels plutôt qu'une liste de longueur variable pour un argument serait assez pervers. – Chuck

+0

Comment déclarer le type de méthode? – youshunei

+0

+ (id) arrayWithObjects: (NSArray *) params; <= comme ça? – youshunei

7

Une autre option pour plusieurs arguments en option est de les passer tous dans un NSDictionary:

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

déclare alors que le dictionnaire des options peut contenir:

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

vous pouvez alors permettre une des touches être absent et même le dictionnaire lui-même pourrait être nul.

+2

Ceci est très commun dans Ruby. La création d'un dictionnaire est un peu verbeuse dans ObjC-Cocoa, il est donc préférable de l'enregistrer pour de grands ensembles d'options connexes plutôt que de l'utiliser comme un "raccourci" pour le passage d'argument - cela ressemblerait plus à une route panoramique. Vous perdez également le contrôle de type. – Chuck

+0

Je pense qu'Apple l'utilise aussi pour certaines méthodes, comme dans les chaînes de caractères. –

1

Pour éviter la question Parse: « aVariable » utilisé comme nom du paramètre précédent plutôt que dans le cadre du sélecteur vous obtenez du compilateur comme un avertissement que vous devez faire:

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

et vous pouvez appeler la méthode, par exemple:

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

ou

[self printWithParameter:YES color:[UIColor someColor]] // YES instead of 1 
Questions connexes