29 votes

Pourquoi dois-je appeler super -dealloc en dernier et pas en premier?

bon exemple:

 - (void)dealloc {
    [viewController release];
    [window release];
    [super dealloc];
}
 

mauvais exemple:

 - (void)dealloc {
    [super dealloc];
    [viewController release];
    [window release];
}
 

Bien que dans presque tous les autres cas, lors de la substitution d'une méthode, j'appellerais d'abord l'implémentation de la méthode super, dans ce cas, apple appelle toujours [super dealloc] à la fin. Pourquoi?

54voto

cocoafan Points 2766

C'est juste une directive. Vous pouvez appeler d'autres instructions après [super dealloc] . cependant, vous ne pouvez plus accéder aux variables de la superclasse car elles sont publiées lorsque vous appelez [super dealloc] . Il est toujours prudent d'appeler la superclasse à la dernière ligne.

Les clés KVO et dépendantes (déclenchées) peuvent également produire des effets secondaires si elles dépendent de variables membres déjà publiées.

12voto

n3rd Points 3292

Je ne sais rien à propos de la programmation pour l'iPhone, mais je suppose que c'est pour la même raison que les destructeurs ont besoin d'être appelés dans l'ordre inverse. Vous voulez vous assurer que tous vos "déchets" est nettoyé avant d'appeler votre super-classe. Si vous le faites, l'autre façon de contourner les choses peuvent déraper. Par exemple, si votre destructeur besoins d'accéder à la mémoire que le super destructeur a déjà libéré:

class X {
    private Map foo;

    function __construct() {
        foo = new Map();
    }

    function __destruct() {
        foo.free;
    }
}

class Y extends X {
    function __construct() {
        super.__construct();
        map.put("foo", 42);
    }

    function __destruct() {
        super.__destruct();
        if (map.containsKey("foo")) {    // boooooooooom!
            doSomething();
        }
    }
}

Vous ne pouvez pas rencontrer ce problème dans votre code, parce que "vous savez ce que vous faites", mais il est plus sûr et de meilleure pratique de ne pas faire de telles choses.

5voto

Terry Wilcox Points 6999

[super dealloc] libère la mémoire utilisée par votre objet, y compris les pointeurs vers viewController et window. Faire référence aux variables après les avoir libérées est au mieux dangereux.

Voir cette réponse .

2voto

Simo Salminen Points 1836

Voici un exemple réel où [super dealloc] doit être le dernier, sinon l'appel à removeFromRunLoop provoquera un crash. Je ne sais pas ce qui se passe à l'intérieur de removeFromRunLoop de NSOutputStream, mais il semble accéder à «soi» dans ce cas.

Installer:

 [outputStream setDelegate:self];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
 

Dealloc:

 - (void)dealloc {
    if (outputStream) {
        [outputStream close];
        [outputStream removeFromRunLoop:[NSRunLoop currentRunLoop]
                                forMode:NSDefaultRunLoopMode];
        [outputStream release];
        outputStream = nil;
    }
    delegate = nil;
    [super dealloc]; // must be last!
}
 

1voto

Kare Morstol Points 434

Vous avez pratiquement presque [super dealloc] à la fin car cela libère les variables de la superclasse et elles ne sont plus accessibles.

Une exception est si vous avez une sous-classe de UITableViewController qui utilise une autre classe comme délégué de vue de table. Dans ce cas, vous devez libérer le délégué de vue de table après [super dealloc] car la vue de table fait référence au délégué de vue de table et la vue de table doit être libérée en premier.

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