web-dev-qa-db-fra.com

Utilisation de alloc init au lieu de new

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?

336
willc2

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.

285
Jeremy Stanley

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...
137
guitar_freak

+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.

52
Barry Wark

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].

8
Brian Campbell

Une réponse courte est:

  1. 'new' ne fonctionne qu'avec l'initialiseur 'init' de base et ne fonctionnera pas avec d'autres initialiseurs (par exemple initWithString :).
  2. .
7
user739711

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.

3
evdude100

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.

3
MurderDev

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].

1
Mike Crawford