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, puisque j'ai lu qu'ils sont équivalents?
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 (comme initWithString
)alloc-init
est plus explicite que new
L’opinion générale semble être que vous devriez utiliser ce que vous êtes à l’aise.
Très vieille question, mais j'ai écrit quelques exemples juste pour le plaisir - peut-être que vous le trouverez utile;)
#import "InitAllocNewTest.h"
@implementation InitAllocNewTest
+(id)alloc{
NSLog(@"Allocating...");
return [super alloc];
}
-(id)init{
NSLog(@"Initializing...");
return [super init];
}
@end
En fonction principale les deux déclarations:
[[InitAllocNewTest alloc] init];
et
[InitAllocNewTest new];
donner le même résultat:
2013-03-06 16:45:44.125 XMLTest[18370:207] Allocating... 2013-03-06 16:45:44.128 XMLTest[18370:207] Initializing...
+new
est équivalent à +alloc/-init
dans l'implémentation d'Apple NSObject
. Il est très peu probable que cela change jamais, mais en fonction de votre niveau de paranoïa, la documentation d'Apple pour +new
semble permettre un changement d'implémentation (et de rupture de 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 Java venus récemment d'Objective-C grâce à leur utilisation persistante de +new
.
Fréquemment, 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 cela, vous prenez l'habitude de le faire de cette façon et ainsi [[SomeObject alloc] init]
peut venir plus naturellement que [SomeObject new]
.
Une réponse courte est:
Pour la note de côté, j’utilise personnellement [Foo new]
si je veux que quelque chose dans init soit fait sans utiliser sa valeur de retour n’importe où. Si vous n'utilisez pas le retour de [[Foo alloc] init]
nulle part, vous recevrez un avertissement. Plus ou moins, j'utilise [Foo new]
pour le plaisir des yeux.
Je suis très en retard pour cela, mais je tiens à mentionner que cette nouvelle est réellement dangereuse dans le monde Obj-C avec Swift. Swift ne créera une méthode init par défaut que si vous ne créez aucun autre initialiseur. Appeler new sur une classe Swift avec un initialiseur personnalisé provoquera un crash. Si vous utilisez alloc/init, le compilateur se plaint correctement que init n'existe pas.
Si new fait le travail à votre place, votre code sera également légèrement réduit. Si vous appelez autrement [[SomeClass alloc] init]
à de nombreux endroits de votre code, vous créerez un point chaud dans l'implémentation de new, c'est-à-dire dans l'exécution, afin de réduire le nombre d'erreurs dans le cache.
À ma connaissance, si vous devez utiliser un initialiseur personnalisé, utilisez [[SomeClass alloc] initCustom]
.
Sinon, utilisez [SomeClass new]
.