2010-03-10 4 views
5

L'une de ces deux façons de créer et d'initialiser un objet est-elle préférable?Objectif C - moyen préféré pour créer et initialiser un objet

MyClass oClass = [[MyClass alloc] init]; 
oClass.length = 5; 
oClass.text = @"Hello"; 

ou en utilisant une méthode de classe qui contient environ le même code mais ressemble à ceci:

MyClass oClass = [MyClass myClassWithLength:(int) 5 andText:(NSString *) @"Hello"]; 

Je déteste quand je vois les choses plus d'une façon et je ne sais pas si l'on est mieux que l'autre, ou pourquoi!

+0

voulez-vous dire [MyClass myClassWithLength: ...? – Ross

+2

Il n'y a jamais une méthode de classe qui sera appelée 'initWith ...' - les méthodes init sont toujours des méthodes d'instance. Ce sera toujours '[[MyClass alloc] initWith ...]'. Les cours offrent parfois des commodités aux constructeurs comme le demande Ross. Juste pour être clair. – Chuck

Répondre

8

Ne soyez pas un ennemi. :-)

Soit dit en passant, je suppose que vous vouliez dire:

(Edit: supprimés moulages inutiles)

MyClass oClass = [[MyClass alloc] initWithLength:5 andText:@"Hello"]; 

La raison de plusieurs méthodes d'initialisation ... est de faire il est plus pratique pour les développeurs de créer des instances correctement initialisées. Ainsi, par exemple, si vous trouvez que les développeurs ont souvent besoin de créer des instances de MyClass avec une longueur et du texte, vous leur facilitez la vie en fournissant une API qui leur permet de le faire en une seule étape. Et si vous trouvez que les développeurs ont souvent besoin de créer des instances de MyClass avec juste une chaîne de texte, vous pouvez également fournir une méthode -initWithText:. Et si les instances créées de cette manière sont fréquemment utilisées comme des objets temporaires (non stockées dans des variables d'instance ou des variables statiques), vous pouvez également ajouter une méthode de commodité de classe comme +myClassWithText: qui retourne une instance auto-libérée de MyClass initialisée avec le chaîne de texte fournie. En ce qui concerne le mieux: il est toujours préférable d'initialiser complètement un objet lorsque cela est possible, donc si l'objet nécessite que les deux valeurs soient correctement initialisées, utilisez la méthode qui vous permet de fournir les deux arguments. Et si vous n'avez pas besoin de stocker une référence à l'instance que vous créez, utilisez la méthode de commodité de classe pour que votre code n'ait pas à gérer la gestion de la mémoire.

+0

Bon point. Mais il semble que l'exemple de code devrait ressembler à MyClass oClass = [[MyClass alloc] initWithLength: 5 andText: @ "Bonjour"]; sans (int) et (NSString *) avant les arguments correspondants ... – Wildcat

2

Si l'objet est inutilisable sans la longueur et le texte, alors la deuxième option pourrait être meilleure. Si ces champs sont optionnels, alors le premier est meilleur.

Cependant, je ne pense pas qu'il y ait une vérité absolue à cette question.

+1

Et souvent une classe fournira les deux alternatives, par commodité (d'où la nécessité d'un "initialisateur désigné" dans la mise en œuvre de la classe). –

0

Si vous avez une classe avec de nombreuses propriétés, il est très peu probable de les initialiser tous dans une seule ligne de code. Les deux façons fonctionnent bien pour moi.

+0

Il n'y a aucune raison de supposer une correspondance biunivoque entre les propriétés et les valeurs initiales, d'autant plus que + alloc garantit que toutes les variables d'instance (autres que isa) sont initialisées à zéro, ce qui est une valeur par défaut raisonnable. Mais dans les cas où un plus grand nombre de valeurs initiales est réellement utile, vous pouvez envisager d'implémenter une méthode -initWithDictionary:. – jlehr

0

Si une méthode initWithSomething: est disponible et que vous voulez fournir des valeurs initiales pour ces propriétés, je préférerais toujours cela simplement parce que c'est plus simple. Il fonctionnera toujours même avec des versions immuables d'une classe.

Mais aucune méthode init n'est intrinsèquement "meilleure". Les classes ont généralement un ou deux initialiseurs désignés et tous les autres appellent simplement ceux avec des valeurs par défaut - cela ne laisse pas nécessairement les propriétés de l'instance intactes. La documentation d'une classe doit indiquer ce que ses initialisateurs font et quel est l'initialiseur désigné pour la classe. Par exemple, [[NSDate alloc] init] utilise l'initialiseur désigné par NSDate, initWithTimeIntervalSinceReferenceDate:, pour créer un objet de date représentant la date et l'heure actuelles. Par ailleurs, cela signifie également que lorsque vous sous-classez une classe, vous devez seulement remplacer son initialiseur désigné.Puisque les autres appellent cela, ils obtiennent votre nouveau comportement gratuitement.