En apprenant Objective-C et en lisant un exemple de code, je remarque que les objets sont généralement créés à l'aide de cette méthode:
SomeObject *myObject = [[SomeObject alloc] init];
au lieu de:
SomeObject *myObject = [SomeObject new];
Y a-t-il une raison à cela, car j'ai lu qu'ils sont équivalents?
objective-c
oop
willc2
la source
la source
Réponses:
Il y a un tas de raisons ici: http://macresearch.org/difference-between-alloc-init-and-new
Certains sélectionnés sont:
new
ne prend pas en charge les initialiseurs personnalisés (commeinitWithString
)alloc-init
est plus explicite quenew
L'opinion générale semble être que vous devez utiliser tout ce qui vous convient.
la source
+newWithString:
, si vous l'avez déjà implémenté-initWithString
. Pas si commun cependant. Personnellement, je l'utilise toujoursnew
lorsque l'initialiseur désigné estinit
trop court et doux.+newWithString:
. Cela rompt la séparation des préoccupations. Pour quand vous voulez juste utiliser de-init
toute façon, il n'y a aucune raison de ne pas simplement utiliser+new
, cependant.[[NSString alloc] initWithFormat:...]
et[NSString stringWithFormat:...]
sont tous deux équivalents. Voulez-vous dire qu'Apple a violé la séparation des préoccupations et n'aurait pas dû l'implémenter de cette façon? (Remarque: je n'essaie pas d'être condescendant; je voudrais simplement obtenir plus d'informations et savoir si suivre l'exemple d'Apple est parfois une mauvaise idée.)Très vieille question, mais j'ai écrit un exemple juste pour le plaisir - peut-être le trouverez-vous utile;)
Dans la fonction principale, les deux instructions:
et
résultat dans la même sortie:
la source
[[InitAllocNewTest alloc] init]
ne compilera pas tant qu'il[InitAllocNewTest new]
n'est pas affecté. (Excuses pour le manque de sauts de ligne, etc.)+new
est équivalent à+alloc/-init
l'NSObject
implémentation d'Apple . Il est très peu probable que cela change un jour, mais selon votre niveau de paranoïa, la documentation d'Apple+new
semble permettre un changement d'implémentation (et rompre l'équivalence) à l'avenir. Pour cette raison, parce que "explicite vaut mieux qu'implicite" et pour la continuité historique, la communauté Objective-C évite généralement+new
. Cependant, vous pouvez généralement repérer les récents arrivants Java à Objective-C par leur utilisation acharnée de+new
.la source
+new
il existe depuis les jours suivants. Si quelque+new
chose est quelque chose d'un signe de quelqu'un qui a appris l'objc il y a longtemps; Je vois que beaucoup de gens qui reviennent à la langue, ou qui l'ont même écrite pendant des années mais clairement après le boom iOS, n'ont aucune idée de ce que cela+new
signifie. Deuxièmement, comme+new
c'est très ancien et depuis les jours suivants, Apple serait assez fou de le changer d'une manière qui casse l'ancien code, d'autant plus que leurs propres bases de code en sont probablement jonchées.new
idiome vient de Smalltalk. Il est également utilisé dans Ruby, et Objective-C et Ruby tirent une grande partie de leur syntaxe et de leurs conventions de Smalltalk.Souvent, vous devrez passer des arguments à
init
et vous utiliserez donc une méthode différente, telle que[[SomeObject alloc] initWithString: @"Foo"]
. Si vous avez l'habitude d'écrire ceci, vous avez l'habitude de le faire de cette façon et cela[[SomeObject alloc] init]
peut donc venir plus naturellement[SomeObject new]
.la source
Une réponse courte est:
la source
Pour une note latérale, j'utilise personnellement
[Foo new]
si je veux que quelque chose en init soit fait sans utiliser sa valeur de retour n'importe où. Si vous n'utilisez pas le retour de[[Foo alloc] init]
n'importe où, vous obtiendrez un avertissement. Plus ou moins, j'utilise[Foo new]
des bonbons pour les yeux.la source
Je suis très en retard à cela, mais je tiens à mentionner que cette nouvelle est en fait dangereuse dans le monde Obj-C avec Swift. Swift ne créera une méthode d'initialisation par défaut que si vous ne créez aucun autre initialiseur. L'appel de new sur une classe swift avec un initialiseur personnalisé provoquera un plantage. Si vous utilisez alloc / init, le compilateur se plaindra correctement que init n'existe pas.
la source
Si le nouveau fait le travail pour vous, il réduira également légèrement votre code. Si vous appelez autrement
[[SomeClass alloc] init]
à de nombreux endroits différents dans votre code, vous créerez un Hot Spot dans l'implémentation de new - c'est-à-dire dans le runtime objc - qui réduira le nombre de vos ratés de cache.À ma connaissance, si vous devez utiliser un initialiseur personnalisé, utilisez
[[SomeClass alloc] initCustom]
.Si vous ne le faites pas, utilisez
[SomeClass new]
.la source
init
fonction par défaut et utilisez-la.[[SomeClass alloc] init];
Si vous avez besoin de paramètres, ne faites toujours jamais quelque chose comme ça, faites-le[[SomeClass alloc] initWith:...];
. Enfin, si vous remplacez lainit
fonction par une implémentation personnalisée, vous pouvez faire appelnew
à la création d'un objet, et il appellera toujours l'init
implémentation personnalisée .