web-dev-qa-db-fra.com

Pour ARC ou pas pour ARC? Quels sont les avantages et inconvénients?

Je n'ai pas encore utilisé ARC, car la majorité du code du projet sur lequel je travaille en ce moment a été écrit avant iOS 5.0.

Je me demandais simplement, est-ce que la commodité de ne pas conserver/publier manuellement (et probablement du code plus fiable qui en résulte?) L'emporte sur tout "coût" d'utilisation d'ARC? Quelles sont vos expériences de l'ARC et le recommanderiez-vous?

Alors:

  • Quel avantage l'ARC peut-elle apporter à un projet?
  • ARC a-t-il un coût similaire à la collecte des ordures en Java?
  • Avez-vous utilisé ARC et si oui, comment l'avez-vous trouvé jusqu'à présent?
112
Simon Withington

Il n'y a aucun inconvénient. Utilise le. Fais-le aujourd'hui. C'est plus rapide que votre ancien code. Il est plus sûr que votre ancien code. C'est plus simple que votre ancien code. Ce n'est pas un ramasse-miettes. Il n'a pas de surcharge d'exécution GC. Le compilateur insère conserve et libère dans tous les endroits que vous devriez avoir de toute façon. Mais il est plus intelligent que vous et peut optimiser celles qui ne sont pas réellement nécessaires (tout comme il peut dérouler des boucles, éliminer les variables temporaires, les 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 Twitch pendant environ une semaine lorsque vous verrez le code ARC. Vous vous en sortirez très rapidement.

  • Il y a quelques (très) petites complications dans la transition vers le code Core Foundation. Il y a un peu plus de complications à traiter tout ce qui traite un id comme un void*. Des choses comme les tableaux C de id peuvent demander un peu plus de réflexion pour faire correctement. Une manipulation sophistiquée d'ObjC va_args Peut également causer des problèmes. La plupart des choses impliquant des mathématiques sur un pointeur ObjC sont plus délicates. De toute façon, vous ne devriez pas en avoir beaucoup.

  • Vous ne pouvez pas mettre un id dans un struct. C'est assez rare, mais parfois il est utilisé pour emballer des données.

  • Si vous n'avez pas suivi un nom KVC correct et que vous mélangez du code ARC et du code 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 tout est du code ARC, cela n'a pas d'importance car il fera le même "mauvais" des deux côtés. Mais s'il s'agit d'un mélange ARC/non-ARC, il y a un décalage.

  • ARC perdra de la mémoire lors des lancements d'exceptions ObjC. Une exception ObjC devrait être très proche de la fin de votre programme. Si vous interceptez un nombre important d'exceptions ObjC, vous les utilisez incorrectement. Cela peut être résolu en utilisant -fobjc-arc-exceptions, Mais cela entraîne les pénalités décrites ci-dessous:

  • ARC ne perdra pas de mémoire lors des levées d'exceptions ObjC ou C++ dans le code ObjC++, mais cela se fait au détriment des performances spatiales et temporelles. C'est encore un 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.)

  • Les pointeurs __weak Ne fonctionnent pas correctement sur iOS 4 ou Mac OS X 10.6, ce qui est dommage, mais assez facile à contourner. Les pointeurs __weak Sont excellents, mais ils ne sont pas le point de vente n ° 1 d'ARC.

Pour 95% + de 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 passer -fno-objc-arc Fichier par fichier. Xcode rend malheureusement cela beaucoup plus difficile qu'il ne devrait l'être dans la pratique. Vous devriez probablement déplacer le code non-ARC dans un xcodeproj distinct pour simplifier cela.

En conclusion, passez à ARC dès que vous le pouvez et ne regardez jamais en arrière.


[~ # ~] modifier [~ # ~]

J'ai vu quelques commentaires allant dans le sens de "l'utilisation d'ARC ne remplace pas la connaissance des règles de gestion de la mémoire Cocoa". C'est surtout vrai, mais il est important de comprendre pourquoi et pourquoi pas. Tout d'abord, si tout votre code utilise ARC et que vous violez les Three Magic Words partout, vous n'aurez toujours aucun problème. C'est choquant de dire, mais voilà. ARC peut conserver certaines choses que vous ne vouliez pas qu'il conserve, 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 nommage de la gestion de la mémoire tout en discutant du nommage KVC. Avec ARC, je pense que vous pourriez réellement devenir un programmeur débutant décent sans apprendre du tout les règles de gestion de la mémoire.

Mais vous ne pouviez pas devenir un programmeur intermédiaire décent. Vous devez connaître les règles afin de faire le pont correctement avec Core Foundation, et chaque programmeur intermédiaire doit gérer 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 les pointeurs void* Vers id (dont vous avez toujours besoin pour exécuter correctement KVO). Et les blocs ... eh bien, la gestion de la mémoire des blocs est juste bizarre.

Donc, mon point est que la gestion de la mémoire sous-jacente est toujours importante, mais 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 que les nouveaux développeurs pensent en termes de graphes d'objets plutôt que de se remplir la tête avec les appels sous-jacents à objc_retain().

147
Rob Napier

Des réponses meilleures et plus techniques que les miennes viendront, mais voici:

  • ARC! = Garbage collection. Il n'y a pas de pénalité de temps d'exécution, cela se fait au moment de la compilation.
  • ARC aussi! = Il suffit de tout libérer automatiquement, comme vous le suggérez dans votre commentaire. Lisez les docs
  • C'est génial une fois que vous réalisez combien de gestion de référence manuelle vous faisiez
  • Utilise le!
  • Un inconvénient - le maintien de l'ancien code non arc devient soudainement très fastidieux.
20
jrturton

Quel avantage l'ARC peut-elle apporter à un projet?

L'avantage est un degré important de protection contre les erreurs courantes de gestion de la mémoire. Les fuites causées par la non-libération d'un objet et les plantages dus à la non-conservation ou à la libération prématurée d'un objet doivent être considérablement réduits. Vous devez toujours comprendre le modèle de mémoire comptée par référence afin de pouvoir classer vos références comme fortes ou faibles, éviter les cycles de rétention, etc.

Combien coûte la collecte des ordures?

Il n'y a pas de récupération de place dans iOS. ARC est similaire à GC en ce que vous n'avez pas besoin de conserver ou de libérer manuellement des objets. C'est différent de GC en ce qu'il n'y a pas de ramasse-miettes. Le modèle de conservation/libération 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.

Avez-vous utilisé ARC et si oui, comment l'avez-vous trouvé jusqu'à présent?

C'est un peu déconcertant si vous avez l'habitude de référencer le comptage, mais c'est juste une question de s'y habituer et d'apprendre à croire que le compilateur fera vraiment la bonne chose. Cela ressemble à une continuation du changement de propriétés fourni avec Objective-C 2.0, qui était une autre grande étape vers la simplification de la gestion de la mémoire. Sans les appels de gestion manuelle 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.

16
Caleb

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 véritable problème à prendre en compte est la propriété des objets et les graphiques d'objet (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, sources de stress et sujettes aux erreurs, donc mieux déléguées à une machine (le compilateur, dans ce cas).

Cela dit, je suis personnellement 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.

4
Nicolas Miari

Le seul inconvénient que j'ai rencontré est que vous utilisez une bibliothèque avec beaucoup de fonctions et de données CoreFoundation. Dans MRC, vous n'avez pas à vous soucier de l'utilisation d'un CFStringRef au lieu d'un NSString*. Dans ARC, vous devez spécifier comment les deux interagissent (pont de base? Libérer l'objet CoreFoundation et le déplacer vers ARC? Faire un objet Cocoa en tant qu'objet retenu +1 CoreFoundation?) De plus, sous OS X, il n'est disponible que sur 64- code bit (même si j'ai un en-tête qui fonctionne autour de ça…).

2
MaddTheSane

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 ne provoquent pas de boucles de référence si vous codez vous-même votre interface utilisateur, le concepteur a tendance à faire du bon travail automatiquement si vous configurez votre interface graphique en l'utilisant.

2
Joachim Isaksson