Pourquoi autorelease est-il particulièrement dangereux / coûteux pour les applications iPhone?
Je suis à la recherche d'une source primaire (ou une très bonne explication) pour sauvegarder l'affirmation que l'utilisation de autorelease
est dangereux ou trop cher lors de l'écriture de logiciels pour l'iPhone.
Plusieurs développeurs font de cette affirmation, et j'ai même entendu dire qu'Apple ne le recommande pas, mais je n'ai pas été en mesure de tourner des sources à l'appui.
DONC les références:
autorelease-iphone
Pourquoi est-ce que cela crée une fuite de mémoire (iPhone)?
Note: je peux le voir, à partir d'un point de vue conceptuel, qui autorelease
est légèrement plus cher qu'un simple appel à release
mais je ne pense pas que les petits pénalité est assez pour faire d'Apple recommande contre elle.
C'est quoi la vraie histoire?
source d'informationauteur e.James
Vous devez vous connecter pour publier un commentaire.
(ne peut pas accepter votre propre réponse?)
Bien, après tout cela, j'ai réussi à trouver une référence à partir des Développeurs d'Apple, a ajouté une note au bas de la page:
Encore, il suggère d'utiliser autorelease avec soin, ne pas éviter complètement.
(et maintenant pour mon commentaire)
Ça sonne comme il est un certain montant de frais généraux dans le maintien de la piscine. J'ai lu cet article qui me conduirait probablement à éviter autorelease, autant que possible, parce que je préfère les choses pour être cohérent. Si vous avez un peu de mémoire en vertu de l'autorelease et d'autres mémoire étant totalement gérés manuellement, il peut être un peu plus de confusion.
Ce n'est pas la question d'utiliser ou de ne pas utiliser autorelease, parce que, dans certains cas, autorelease est la seule façon que vous allez obtenir. La question devrait être "Pourquoi ne pas utiliser autorelease sur tous les objets, au lieu d'utiliser les conserver et de les libérer?".
Pour répondre à cela, vous devez d'abord apprendre ce qu'est une bonne utilisation de autorelease. Disons que vous avez une classe qui a deux propriétés: firstName et lastName. Il y a un getter et un setter pour chaque. Mais vous avez aussi besoin d'une méthode qui retourne fullName, par la concaténation de ces deux chaînes en une nouvelle marque de la chaîne:
Quel est le problème avec cette image? Le nombre de références sur la chaîne de retour est 1, donc si vous ne voulez pas de fuite, l'appelant devrait le sortir quand il est fait. À partir de l'appelant point de vue, il a juste demandé une valeur de propriété
fullName
. Il est pas au courant du fait qu'il a pu une nouvelle marque de l'objet qu'il doit libérer après utilisation, et non pas une référence à un NSString en interne organisé par la classe!Si nous mettons le
[str release]
avant le retour, la chaîne serait détruit et la méthode serait de retour des ordures! C'est là que nous utilisons[str autorelease]
à l'occasion de l'objet pour la version à une date ultérieure (généralement lorsque le traitement des événements est fait). De cette façon, l'appelant obtient son objet, et ne pas avoir à se soucier de savoir s'il devrait le sortir ou pas.La convention est d'appeler autorelease sur un nouvel objet avant que la méthode retourne à l'appelant. Les Exceptions sont des méthodes dont les noms commencent par
alloc
new
oucopy
. Dans de tels cas, les appelants savoir qu'une marque nouvel objet est créé et il est de leur devoir d'appeler release sur cet objet.Remplacement de la libération avec autorelease, est une mauvaise idée, puisque les objets accumuler et obstruer la mémoire très rapidement, surtout dans les boucles. Les ressources sur l'iPhone sont limitées, afin de minimiser la mémoire accaparer, il est de votre devoir de libérer l'objet dès que vous avez terminé avec elle.
Je suis en désaccord que le fait d'éviter autorelease, est sage.
Cocoa Touch utilise assez fréquemment à l'interne et pour de nombreuses situations, c'est la seule façon d'allouer la mémoire correctement (un bon exemple est réutilisable vue de la table de cellules). Si vous comprenez ce qui se passe, l'autorelease pool est un excellent outil à votre disposition. La principale chose à retenir est que les blocs ne sont pas libérés jusqu'à un certain point plus tard dans l'exécution de la boucle. Si vous exécutez une boucle serrée, sans interaction de l'utilisateur et s'accumulent autorelease blocs, vous allez finir par manquer de mémoire.
Autorelease est pas un substitut pour la collecte des ordures (non disponible dans le SDK de l'iPhone) et peut conduire à de mauvaises balançant pointeur de bugs (le pointeur semble toujours être la bonne, puis à un certain imprévisible point de passe non valide), mais est également très utile dans la rédaction claire et facile d'entretien code. Considérons le cas suivant:
La chaîne de chemin d'accès est généré sous la forme d'un autorelease objet. Nous ne sommes pas obligés de créer un objet temporaire, nous avons donc éviter que les frais généraux (et la possibilité que nous pourrions oublier de le libérer). Le mémoire sera entièrement dégagée (pas de fuite), juste qu'il arrivera plus tard dans l'exécution de la boucle. Demandez-vous: suis-je allouer des centaines de ces avant que je sois de retour à la saisie de l'utilisateur? Si non (comme ce serait le cas ici), autorelease est une excellente solution et en effet ce NSString méthode pour travailler avec les chemins d'accès est disponible uniquement à l'aide de autoreleased mémoire.
Je suis d'accord avec ci-dessus affiche qu'à la suite de la convention et d'être en harmonie, c'est une très bonne idée.
J'ai tendance à éviter d'utiliser autorelease sur l'iPhone où je peux (comme Jon points, vous ne pouvez pas toujours faire sans elle), tout simplement parce que j'aime savoir que les objets que je travaille avec l'instant je n'ai pas besoin d'eux. De mémoire, les contraintes sont l'un des plus grands problèmes que vous devrez faire face à l'appareil et je crois qu'ils sont la source de la plupart des problèmes de plantage, vous trouverez là-bas.
Comme mis en évidence par Apple, un domaine particulier de préoccupation lorsque vous utilisez autoreleased objets à l'intérieur de tout type de boucle, parce qu'ils s'entassent au sein de l'autorelease pool. Ensuite, vous aurez à gérer quand vidanger la piscine ou de créer /libération. Faire ça à chaque passage dans la boucle peut dégrader les performances, mais de trop nombreux cols sans pourrait conduire à une dangereuse l'utilisation de la mémoire. Je suis encore à peaufiner ce dans les Molécules, parce qu'il y a intermittente des problèmes de mémoire lors de l'importation de large (>2 MO) des fichiers texte à partir de la Protein Data Bank. J'ai été en mesure d'améliorer les performances en réduisant autoreleased objets, mais ne pouvait pas les éliminer complètement.
Une autre zone à surveiller est l'aide de autoreleased objets avec les threads. Si possible, ne pas utiliser de autoreleased objets lorsque vous traitez avec des méthodes effectuée sur un thread d'arrière-plan, parce que la piscine peut être vidé à des moments aléatoires. Cela conduit à des plantages intermittents qui peut vraiment s'amuser à traquer.
Je vous suggère fortement d'éviter autorelease comme de la peste. Gestion de la mémoire, des bugs sont une excellente façon de déchets d'énormes quantités de temps et d'argent, j'ai eu l'honneur douteux d'aller à travers le processus plusieurs fois sur les vieux Mac apps, et le fait que l'iPhone a serré les contraintes de mémoire signifie que vous devez être extrêmement prudent, ou l'application va juste être instable et souvent planter...comme beaucoup de premières applications qui ont été publiées l'été dernier.
Le seul moyen que j'ai trouvé pour écrire stable applications iPhone est de gérer l'ensemble de votre mémoire vous-même, et de le faire de manière cohérente. Même si vous êtes le seul programmeur sur votre projet, vous vous remercierez plus tard. Il peut être difficile si vous avez appris à programmer dans des langages que "prendre soin de tout pour vous," mais il est vraiment la peine d'apprendre comment le faire bien, si vous êtes sérieux au sujet de createing de la qualité des applications de l'iPhone.