164 votes

En Objective-C, pourquoi devrais-je vérifier si self = [super init] n'est pas nul?

J'ai une question d'ordre général au sujet de l'écriture init méthodes en Objective-C.

Je la vois partout (Apple code, les livres, le code open source, etc.) qu'une méthode init doit vérifier si self = [super init] n'est pas nul, avant de poursuivre avec d'initialisation.

La valeur par défaut d'Apple modèle pour une méthode init est:

- (id) init
{
    self = [super init];

    if (self != nil)
    {
        // your code here
    }

    return self;
}

Pourquoi?

Je veux dire, quand est-init jamais aller retour néant? Si j'ai appelé init sur NSObject et suis nul en arrière, alors quelque chose doit vraiment être vissée, droite? Et dans ce cas, vous pourriez aussi bien ne pas même écrire un programme...

Est-ce vraiment commun qu'une classe " init méthode peut retourner néant? Si oui, dans quels cas et pourquoi?

53voto

iKenndac Points 14855

Par exemple:

 [[NSData alloc] initWithContentsOfFile:@"this/path/doesn't/exist/"];
[[NSImage alloc] initWithContentsOfFile:@"unsupportedFormat.sjt"];
[NSImage imageNamed:@"AnImageThatIsntInTheImageCache"];
 

... etc. (Remarque: NSData peut lever une exception si le fichier n'existe pas). Il y a quelques domaines où le retour de zéro est le comportement attendu quand un problème survient, et à cause de cela, il est de pratique courante de vérifier à peu près zéro tout le temps, par souci de cohérence.

50voto

bbum Points 124887

Cet idiome est standard, car il fonctionne dans tous les cas.

Bien que rare, il y aura des cas où...

[super init];

... retourne une instance à l'autre, ce qui nécessite l'affectation de soi.

Et il y a des cas où il sera de retour nul, nécessitant donc le néant, vérifiez donc que votre code ne fonctionne pas, essayez d'initialiser une variable d'instance logement qui n'existe plus.

La ligne de fond est que c'est la documentée modèle correct à utiliser et, si vous ne l'utilisez pas, vous le faites mal.

26voto

Gino Points 354

Je pense que, dans la plupart des classes, si la valeur de retour de [super init] est nulle, et vous cochez la case, tel que recommandé par la norme de pratiques, puis un retour prématuré si nul, fondamentalement, votre application est encore de ne pas fonctionner correctement. Si vous pensez à ce sujet, même si celui si (auto != néant) vérifier est là, pour le bon fonctionnement de votre classe, 99,99% du temps que vous ne besoin de soi pour être non-nulle. Maintenant, supposons que, pour quelque raison que ce soit, [super init] n'a retourner nil, fondamentalement votre chèque à l'encontre de néant est fondamentalement renvoyer la balle jusqu'à l'appelant de votre classe, où il échouerait probablement de toute façon, puisqu'il sera naturellement supposer que l'appel a été couronnée de succès.

Fondamentalement, ce que je veux en venir c'est que 99,99% du temps, le si (auto != néant) ne pas acheter quoi que ce soit en termes de plus grande robustesse, puisque vous êtes juste en passant la balle à votre invocateur. Pour vraiment être en mesure de gérer ce robuste, vous avez réellement besoin de mettre des contrôles dans l'ensemble de votre appel hiérarchie. Et même alors, la seule chose qu'elle allait acheter pour vous est que votre application manquerait un peu plus proprement/robuste. Mais il serait encore échouer.

Si une bibliothèque de classe arbitrairement décidé de retourner nil comme un résultat de [super init], vous êtes assez bien f***ed de toute façon, et c'est plus d'une indication que l'auteur de la bibliothèque de la classe fait une erreur de mise en œuvre.

Je pense que c'est plus un héritage de codage suggestion, lorsque des applications couru beaucoup, beaucoup plus de mémoire limitée.

Mais pour C niveau code, je serais toujours vérifier la valeur de retour de malloc() à l'encontre d'un pointeur NULL. Attendu que, pour Objective-C, jusqu'à ce que je trouve les preuves du contraire, je pense que je vais généralement sauter le si (auto != néant) vérifie. Pourquoi cette différence ?

Parce que, à la C et la fonction malloc niveaux, dans certains cas, vous pouvez récupérer en partie. Alors que je pense en Objective-C, dans 99,99% des cas, si [super init] ne retourner nil, vous êtes essentiellement en f***ed, même si vous essayez de le manipuler. Vous pourriez tout aussi bien laisser l'application crash et traiter le lendemain.

8voto

Pumbaa80 Points 27066

C'est une sorte de résumé des commentaires ci-dessus.

Disons que la super-classe retours nil. Ce qui va se passer?

Si vous ne suivez pas les conventions

Votre code va crash dans le milieu de votre init méthode. (à moins d' init n'a rien de l'importance)

Si vous suivez les conventions, ne sachant pas que la super-classe peut retourner nil (la plupart des gens finissent par ici)

Votre code est probalby va bloquer à un certain moment plus tard, parce que votre exemple est - nil, où que vous attendiez quelque chose de différent. Ou que votre programme va se comporter de façon inattendue sans s'écraser. Ah! Voulez-vous faire? Je ne sais pas...

Si vous suivez les conventions, volontiers en permettant à votre sous-classe pour retourner nil

Votre code de documentation(!) doit indiquer clairement: "de retour ... ou le néant", et le reste de votre code doit être préparé pour la manipulation de ce. Maintenant, il fait sens.

7voto

John Rudy Points 16436

En règle générale, si votre classe dérive directement de NSObject , vous n'en aurez pas besoin. Cependant, c'est une bonne habitude à prendre, comme si votre classe dérive d'autres classes, leurs initialiseurs peuvent renvoyer nil , et si c'est le cas, votre initialiseur peut alors capturer cela et se comporter correctement.

Et oui, pour l'anecdote, je suis la meilleure pratique et je l'écris sur toutes mes classes, même celles qui dérivent directement de NSObject .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X