Je n'ai pas encore utilisé ARC, car la majorité du code du projet sur lequel je travaille actuellement a été écrit avant iOS 5.0.
Je me demandais simplement si la commodité de ne pas conserver / publier manuellement (et probablement un code plus fiable qui en résulte?) L'emporte-t-elle sur le `` coût '' de l'utilisation d'ARC? Quelles sont vos expériences d'ARC, et le recommanderiez-vous?
Alors:
- Quel avantage l'ARC peut-il apporter à un projet?
- ARC a-t-il un coût comme le ramassage des ordures en Java?
- Avez-vous utilisé ARC et si oui, comment l'avez-vous trouvé jusqu'à présent?
iphone
objective-c
ipad
ios5
automatic-ref-counting
Simon Withington
la source
la source
Réponses:
Il n'y a aucun inconvénient. Utilise le. Fais-le aujourd'hui. C'est plus rapide que votre ancien code. C'est plus sûr que votre ancien code. C'est plus facile que votre ancien code. Ce n'est pas un ramassage des ordures. Il n'a pas de surcharge d'exécution du GC. Les inserts du compilateur conservent et publient dans tous les endroits que vous devriez avoir de toute façon. Mais il est plus intelligent que vous et peut optimiser ceux qui ne sont pas réellement nécessaires (tout comme il peut dérouler des boucles, éliminer des variables temporaires, des fonctions en ligne, etc.)
OK, maintenant je vais vous parler des petits inconvénients:
Si vous êtes un développeur ObjC de longue date, vous vous contracterez pendant environ une semaine lorsque vous verrez du code ARC. Vous vous en remettrez très vite.
Il y a quelques (très) petites complications dans le pontage vers le code Core Foundation. Il y a un peu plus de complications dans le traitement de tout ce qui traite un
id
commevoid*
. Des choses comme les tableaux C deid
peuvent prendre un peu plus de réflexion pour faire correctement. Une manipulation sophistiquée d'ObjCva_args
peut également causer des problèmes. La plupart des choses impliquant des mathématiques sur un pointeur ObjC sont plus délicates. Vous ne devriez pas en avoir beaucoup de toute façon.Vous ne pouvez pas mettre un
id
dans unstruct
. C'est assez rare, mais parfois utilisé pour emballer des données.Si vous n'avez pas suivi la dénomination KVC correcte et que vous mélangez du code ARC et non-ARC, vous aurez des problèmes de mémoire. ARC utilise la dénomination KVC pour prendre des décisions sur la gestion de la mémoire. Si c'est tout du code ARC, alors cela n'a pas d'importance car il fera le même "mal" des deux côtés. Mais s'il s'agit d'un mélange ARC / non-ARC, il y a une discordance.
ARC perdra de la mémoire lors des levées d'exceptions ObjC. Une exception ObjC doit être très proche de la fin de votre programme. Si vous détectez un nombre important d'exceptions ObjC, vous les utilisez de manière incorrecte. Ceci peut être corrigé en utilisant
-fobjc-arc-exceptions
, mais il encourt les pénalités décrites ci-dessous:ARC ne perdra pas de mémoire pendant les levées d'exceptions ObjC ou C ++ dans le code ObjC ++, mais cela se fait au détriment des performances en termes de temps et d'espace. Ceci est encore une autre parmi une longue liste de raisons pour minimiser votre utilisation d'ObjC ++.
ARC ne fonctionnera pas du tout sur iPhoneOS 3 ou Mac OS X 10.5 ou version antérieure. (Cela m'empêche d'utiliser ARC dans de nombreux projets.)
__weak
les pointeurs ne fonctionnent pas correctement sur iOS 4 ou Mac OS X 10.6, ce qui est dommage, mais assez facile à contourner.__weak
Les pointeurs sont excellents, mais ils ne sont pas le principal argument de vente d'ARC.Pour plus de 95% du code, ARC est génial et il n'y a aucune raison de l'éviter (à condition que vous puissiez gérer les restrictions de version du système d'exploitation). Pour le code non ARC, vous pouvez transmettre
-fno-objc-arc
fichier par fichier. Xcode rend malheureusement cela beaucoup plus difficile qu'il ne devrait l'être en pratique. Vous devriez probablement déplacer le code non-ARC dans un xcodeproj séparé pour simplifier cela.En conclusion, passez à ARC dès que vous le pouvez et ne regardez jamais en arrière.
ÉDITER
J'ai vu quelques commentaires du genre "l'utilisation d'ARC ne remplace pas la connaissance des règles de gestion de la mémoire Cocoa." C'est généralement vrai, mais il est important de comprendre pourquoi et pourquoi pas. Premièrement, si tout votre code utilise ARC et que vous enfreignez les trois mots magiquespartout, vous n'aurez toujours aucun problème. Choquant à dire, mais voilà. ARC peut conserver certaines choses que vous ne vouliez pas conserver, mais il les libérera également, donc cela n'aura jamais d'importance. Si j'enseignais une nouvelle classe à Cocoa aujourd'hui, je ne passerais probablement pas plus de cinq minutes sur les règles de gestion de la mémoire, et je ne mentionnerais probablement que les règles de dénomination de la gestion de la mémoire lors de la discussion de la dénomination KVC. Avec ARC, je crois que vous pourriez devenir un programmeur débutant décent sans apprendre du tout les règles de gestion de la mémoire.
Mais vous ne pouvez pas devenir un programmeur intermédiaire décent. Vous devez connaître les règles pour établir correctement le lien avec Core Foundation, et chaque programmeur intermédiaire doit traiter avec CF à un moment donné. Et vous devez connaître les règles du code mixte ARC / MRC. Et vous devez connaître les règles lorsque vous commencez à jouer avec des
void*
pointeursid
(dont vous continuez à avoir besoin pour exécuter correctement KVO). Et les blocs ... eh bien, la gestion de la mémoire par blocs est juste bizarre.Donc, mon point est que la gestion de la mémoire sous-jacente est toujours importante, mais là où je passais beaucoup de temps à énoncer et à reformuler les règles pour les nouveaux programmeurs, avec ARC, cela devient un sujet plus avancé. Je préfère amener les nouveaux développeurs à penser en termes de graphes d'objets plutôt que de se remplir la tête avec les appels sous-jacents à
objc_retain()
.la source
De meilleures réponses plus techniques que les miennes viendront, mais voici:
la source
L'avantage est un degré significatif de protection contre les erreurs courantes de gestion de la mémoire. Les fuites causées par l'échec de la libération d'un objet et les plantages dus à l'absence de rétention ou à la libération prématurée d'un objet doivent être considérablement réduites. Vous devez toujours comprendre le modèle de mémoire compté par référence afin de pouvoir classer vos références comme fortes ou faibles, éviter les cycles de rétention, etc.
Il n'y a pas de garbage collection dans iOS. ARC est similaire à GC en ce sens que vous n'avez pas à conserver ou à libérer manuellement les objets. C'est différent de GC en ce qu'il n'y a pas de ramasse-miettes. Le modèle de conservation / publication s'applique toujours, c'est juste que le compilateur insère les appels de gestion de mémoire appropriés dans votre code pour vous au moment de la compilation.
C'est un peu déconcertant si vous êtes habitué au comptage de références, mais c'est juste une question de s'y habituer et d'apprendre à avoir confiance que le compilateur fera vraiment ce qu'il faut. Cela ressemble à une continuation du changement des propriétés fourni avec Objective-C 2.0, qui était un autre grand pas en avant vers la simplification de la gestion de la mémoire. Sans les appels manuels de gestion de la mémoire, votre code devient un peu plus court et plus facile à lire.
Le seul problème avec ARC est qu'il n'est pas pris en charge dans les anciennes versions d'iOS, vous devez donc en tenir compte avant de décider de l'adopter.
la source
Je pense que l'ARC est une excellente idée. Par rapport à GC, vous pouvez avoir votre gâteau et le manger aussi. J'ai tendance à croire que MRC impose une «discipline» inestimable à la gestion de la mémoire que tout le monde gagnerait à avoir. Mais je conviens également que le vrai problème à prendre en compte est la propriété des objets et les graphiques d'objets (comme beaucoup l'ont souligné), et non le nombre de références de bas niveau en soi.
Pour conclure: ARC n'est PAS un laissez-passer gratuit pour ne pas penser à la mémoire; c'est un outil pour aider les humains à éviter les tâches répétitives, qui causent du stress et sont sujettes aux erreurs, donc mieux déléguées à une machine (le compilateur, dans ce cas).
Cela dit, je suis personnellement un peu un artisan et je n'ai pas encore fait la transition. Je viens de commencer à utiliser Git ...
MISE À JOUR: J'ai donc migré tout mon jeu, bibliothèque gl incluse, et aucun problème jusqu'à présent (sauf avec l'assistant de migration dans Xcode 4.2). Si vous démarrez un nouveau projet, allez-y.
la source
Je l'ai utilisé dans quelques projets (certes petits), et je n'ai que de bonnes expériences, à la fois en termes de performances et de fiabilité.
Une petite mise en garde est que vous devez apprendre les choses à faire et à ne pas faire: les références faibles pour ne pas provoquer de boucles de référence si vous codez votre interface utilisateur par vous-même, le concepteur a tendance à faire du bon travail. automatiquement si vous configurez votre interface graphique en l'utilisant.
la source
Le seul inconvénient que j'ai rencontré est si vous utilisez une bibliothèque avec beaucoup de fonctions et de données CoreFoundation. Dans MRC, vous n'aviez pas à vous soucier d'utiliser un
CFStringRef
au lieu d'unNSString*
. Dans ARC, vous devez spécifier comment les deux interagissent (pont de base? Libérer l'objet CoreFoundation et le déplacer vers ARC? Créer un objet Cocoa en tant qu'objet conservé +1 CoreFoundation?) De plus, sous OS X, il n'est disponible que sur 64- code de bit (bien que j'aie un en-tête qui fonctionne autour de ça…).la source