2009-05-19 4 views
0

Est-[[MyObject itemProperty] release] acceptable?Lors de la libération de l'objet appartient à un autre objet - gestion de la mémoire xcode

Actuellement, MyObject récupère des données et les définit sur itemProperty. Le délégué de MyObject se déclenche ensuite et utilise les données itemProperty de MyObject et les libère. Est-ce un moyen acceptable de gestion de la mémoire?

On m'a dit à partir de divers livres que vous ne devriez libérer qu'un objet que vous déclarez. Des astuces ou un moyen alternatif?

Répondre

2

Je vous déconseillerais l'approche que vous décrivez ... votre instinct pour poser une question à ce sujet sur SO est correct car cela va probablement conduire à des problèmes.

Les objets sont responsables de la gestion de leur propre état interne, et avoir un délégué interfère avec cet état interne de cette manière est assez inhabituel. La pratique normale pour le nettoyage de la mémoire est d'avoir MyObject mémoire de libération dans sa méthode dealloc:

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

En fait, si vous implémentez dealloc que vous devriez à ranger MyObject, ayant le délégué envoyer un message de libération l'objet à itemProperty signifie que les objets itemProperty sont libérés deux fois, ce qui laisse le paramètre de conservation de l'objet dans un état inattendu et peut le libérer rapidement. Si jamais vous modifiez l'application pour que d'autres objets utilisent la propriété itemProperty, ils trouveront qu'elle a été mystérieusement désallouée après l'appel du délégué. D'autre part, si vous ne rangez pas la mémoire dans dealloc, vous vous retrouvez dans une situation où vous comptez que le délégué est appelé pour vous assurer que la mémoire est correctement gérée. Pouvez-vous vraiment garantir que la méthode déléguée sera TOUJOURS appelée à un moment donné dans votre application? À coup sûr? Même s'il existe des exceptions ou d'autres conditions d'erreur susceptibles de provoquer un flux d'exécution inhabituel pour votre application?

Même si vous pouvez le garantir, comme la logique de l'application change, cela peut ne plus être le cas et vous oubliez que le délégué effectue la gestion de la mémoire, ce qui entraîne une fuite ou une erreur de segmentation. Certes, d'autres développeurs de cacao conservant votre code ne penseraient pas à regarder le délégué pour la gestion de la mémoire et auraient probablement du mal à déboguer les problèmes qui se posent.

Dans ce cas, demandez au délégué d'utiliser le itemProperty sans le conserver, le relâcher ou le libérer automatiquement (à moins, bien sûr, que le délégué ait besoin de garantir que l'objet sera toujours disponible après, peut-être, MyObject). Lorsque MyObject est désalloué, les données itemProperty seront alors libérées.

0

Généralement, vous ne libérez que lorsque vous allouez, créez ou copiez quelque chose. Étant donné que vous n'avez pas fourni d'autre code que celui de la publication, il est difficile de dire si vous devriez ou non publier. D'après ce que vous avez dit, la meilleure solution semble être d'utiliser le pool autorelease. Après avoir récupéré vos données, appelez MyObject [itemProperty autorelease]. Ensuite, il sera libéré automatiquement après que votre délégué l'a utilisé. Cependant, cela dépend de comment vous faites tout :-)

Encore une fois, plus de code aidera.

0

D'abord, vous ne déclarez pas d'objet. Vos objets créent d'autres objets, les possèdent, les transmettent, etc.

Ne jamais relâcher quelque chose qui ne vous appartient pas. Libérer un objet signifie "Je ne souhaite plus posséder cet objet". Si vous ne le possédez pas déjà, qu'abandonnez-vous? Attendez-vous à une casse lorsque vous faites du mauvais mojo comme ça.

Si vous souhaitez que le propriétaire actuel cesse de le posséder, dites-le. Généralement, ce sera quelque chose comme [myObject setItemProperty:nil] (ou myObject.itemProperty = nil). Ou vous pourriez fournir un nouvel objet. De toute façon, il est de la responsabilité du propriétaire actuel d'arrêter de le posséder.

Questions connexes