Je voudrais savoir dans quelle situation avez-vous utilisé -retainCount
jusqu'à présent, et éventuellement les problèmes qui peuvent survenir en l'utilisant.
Merci.
Je voudrais savoir dans quelle situation avez-vous utilisé -retainCount
jusqu'à présent, et éventuellement les problèmes qui peuvent survenir en l'utilisant.
Merci.
Réponses:
Vous ne devriez jamais utiliser -retainCount
, car cela ne vous dit jamais rien d'utile. La mise en œuvre des frameworks Foundation et AppKit / UIKit est opaque; vous ne savez pas ce qui est conservé, pourquoi il est conservé, qui le conserve, quand il a été conservé, etc.
Par exemple:
[NSNumber numberWithInt:1]
cela aurait un retainCount
de 1. Ce n'est pas le cas. C'est 2.@"Foo"
cela aurait un retainCount
de 1. Ce n'est pas le cas. C'est 1152921504606846975.[NSString stringWithString:@"Foo"]
cela aurait un retainCount
de 1. Ce n'est pas le cas. Encore une fois, c'est 1152921504606846975.Fondamentalement, puisque tout peut conserver un objet (et donc le modifier retainCount
), et puisque vous n'avez pas la source de la plupart du code qui exécute une application, celui d'un objet retainCount
n'a pas de sens.
Si vous essayez de découvrir pourquoi un objet n'est pas désalloué, utilisez l'outil Fuites dans Instruments. Si vous essayez de découvrir pourquoi un objet a été désalloué trop tôt, utilisez l'outil Zombies dans Instruments.
Mais ne l'utilisez pas -retainCount
. C'est une méthode vraiment sans valeur.
Éditer
Veuillez tout le monde aller sur http://bugreport.apple.com et demander qu'il -retainCount
soit obsolète. Plus il y a de gens qui le demandent, mieux c'est.
modifier # 2
En tant que mise à jour, a [NSNumber numberWithInt:1]
maintenant un retainCount
de 9223372036854775807. Si votre code s'attendait à ce qu'il soit 2, votre code est maintenant cassé.
- (NSUInteger)retainCount{return NSUIntegerMax;}
.
retainCount
.
Sérieusement. Ne fais pas ça.
Suivez simplement les directives de gestion de la mémoire et ne publiez que ce que vous alloc
, new
ou copy
(ou tout ce que vous avez retain
initialement appelé ).
@bbum l'a mieux dit ici sur SO , et encore plus en détail sur son blog .
-retainCount
peuvent être obtenues (avec beaucoup plus de détails) à partir d'Instruments et de ses outils.
retain
, retain
, retain
, autorelease,
autorelease, autorelease
pourrait être un résultat tout à fait valable de passer un objet à travers l'API UIKit, par exemple.
Les objets libérés automatiquement sont un cas où la vérification de -retainCount n'est pas informative et peut être trompeuse. Le nombre de retenues ne vous dit rien sur le nombre de fois où -autorelease a été appelé sur un objet et par conséquent combien de fois il sera libéré lorsque le pool de libération automatique en cours se videra.
Je ne trouve retainCounts très utile lorsque vérifiée à l' aide « instruments ».
À l'aide de l'outil «allocations», assurez-vous que l'option «Enregistrer le nombre de références» est activée et que vous pouvez accéder à n'importe quel objet et voir son historique retentionCount.
En associant allocs et versions, vous pouvez obtenir une bonne image de ce qui se passe et résoudre souvent les cas difficiles où quelque chose n'est pas publié.
Cela ne m'a jamais laissé tomber - y compris la recherche de bogues dans les premières versions bêta d'iOS.
Jetez un œil à la documentation Apple sur NSObject, elle couvre à peu près votre question: NSObject retentionCount
En bref, retentionCount est probablement inutile pour vous à moins que vous n'ayez implémenté votre propre système de comptage de références (et je peux presque garantir que vous ne l'aurez pas).
Selon les propres mots d'Apple, retentionCount est "généralement sans valeur dans le débogage des problèmes de gestion de la mémoire".
Bien sûr, vous ne devez jamais utiliser la méthode retentionCount dans votre code, car la signification de sa valeur dépend du nombre de versions automatiques appliquées à l'objet et c'est quelque chose que vous ne pouvez pas prévoir. Cependant, il est très utile pour le débogage - en particulier lorsque vous recherchez des fuites de mémoire dans le code qui appelle des méthodes d'objets Appkit en dehors de la boucle d'événements principale - et il ne devrait pas être obsolète.
Dans vos efforts pour faire valoir votre point de vue, vous avez sérieusement surestimé la nature insondable de la valeur. Il est vrai que ce n'est pas toujours un décompte de référence. Certaines valeurs spéciales sont utilisées pour les indicateurs, par exemple pour indiquer qu'un objet ne doit jamais être désalloué. Un nombre comme 1152921504606846975 semble très mystérieux jusqu'à ce que vous l'écriviez en hexadécimal et obteniez 0xfffffffffffffff. Et 9223372036854775807 est 0x7fffffffffffffff en hexadécimal. Et il n'est vraiment pas si surprenant que quelqu'un choisisse d'utiliser des valeurs comme celles-ci comme indicateurs, étant donné qu'il faudrait près de 3000 ans pour obtenir un retentionCount aussi élevé que le plus grand nombre, en supposant que vous incrémentiez le retentionCount 100000000 fois par seconde.
Quels problèmes pouvez-vous rencontrer en l'utilisant? Tout ce qu'il fait est de renvoyer le nombre de rétention de l'objet. Je ne l'ai jamais appelé et je ne vois aucune raison pour laquelle je le ferais. Je l'ai remplacé dans les singletons pour m'assurer qu'ils ne sont pas désalloués.
retainCount
pour la gestion de la mémoire.
Vous ne devriez pas vous inquiéter des fuites de mémoire tant que votre application n'est pas opérationnelle et ne fait pas quelque chose d'utile.
Une fois que c'est le cas, lancez Instruments et utilisez l'application et voyez si des fuites de mémoire se produisent vraiment. Dans la plupart des cas, vous avez créé un objet vous-même (vous le possédez donc) et avez oublié de le libérer après avoir terminé.
N'essayez pas d'optimiser votre code au fur et à mesure que vous l'écrivez, vos suppositions sur ce qui pourrait perdre de la mémoire ou prendre trop de temps sont souvent fausses lorsque vous utilisez réellement l'application normalement.
Essayez d'écrire du code correct, par exemple si vous créez un objet en utilisant alloc et autres, assurez-vous de le libérer correctement.
-retainCount
.