Propriétés sous ARC: toujours ou uniquement publiques?

9

Il y a un peu moins de deux ans, après avoir lu un article humblement intitulé "Les commandements de code: meilleures pratiques pour le codage Objective-C" par Robert McNally , j'ai adopté la pratique d'utiliser des propriétés pour à peu près tous les membres de données de mes classes Objective-C ( 3e commandement en mai 2012). McNally énumère ces raisons pour le faire (c'est moi qui souligne):

  1. Les propriétés appliquent des restrictions d'accès (comme en lecture seule)
  2. Les propriétés appliquent la politique de gestion de la mémoire (forte, faible)
  3. Les propriétés permettent d'implémenter de manière transparente des setters et des getters personnalisés.
  4. Les propriétés avec des setters ou des getters personnalisés peuvent être utilisées pour appliquer une stratégie de sécurité des threads.
  5. Avoir une seule façon d'accéder aux variables d'instance augmente la lisibilité du code.

Je mets la plupart de mes propriétés dans des catégories privées, donc les numéros 1 et 4 ne sont généralement pas des problèmes auxquels je suis confronté. Les arguments 3 et 5 sont plus «souples» et, avec les bons outils et autres consistances, ils pourraient devenir non problématiques. Enfin, pour moi, le plus influent de ces arguments était le numéro 2, la gestion de la mémoire. Je fais ça depuis.

@property (nonatomic, strong) id object; // Properties became my friends.

Pour mes derniers projets, je suis passé à l'utilisation d'ARC, ce qui m'a fait douter que la création de propriétés pour à peu près n'importe quoi soit toujours une bonne idée ou peut-être un peu superflue. ARC s'occupe de la gestion de la mémoire des objets Objective-C pour moi, ce qui fonctionne bien pour la plupart des strongmembres si vous déclarez simplement les ivars. Les types C que vous deviez gérer manuellement de toute façon, avant et après ARC, et les weakpropriétés sont principalement publiques.

Bien sûr, j'utilise toujours des propriétés pour tout ce qui nécessite un accès depuis l'extérieur de la classe, mais ce ne sont pour la plupart qu'une poignée de propriétés, tandis que la plupart des membres de données sont répertoriés comme des ivars sous l'en-tête de l'implémentation

@implementation GTWeekViewController
{
    UILongPressGestureRecognizer *_pressRecognizer;
    GTPagingGestureRecognizer *_pagingRecognizer;
    UITapGestureRecognizer *_tapRecognizer;
}

En tant qu'expérience, j'ai fait cela un peu plus rigoureusement, et l'abandon des propriétés pour tout a de beaux effets secondaires positifs.

  1. Les exigences de code de membre de données ( @property/ @synthesize) ont été réduites à la seule déclaration ivar.
  2. La plupart de mes self.somethingréférences ont été nettoyées juste _something.
  3. Il est facile de distinguer quels membres de données sont privés (ivars) et lesquels sont publics (propriétés).
  4. Enfin, il `` semble '' plus que c'était le but pour lequel Apple souhaitait les propriétés, mais c'est une spéculation subjective.

Passons à la question : je glisse lentement vers le côté obscur, en utilisant de moins en moins de propriétés en faveur des ivars d'implémentation. Pouvez-vous m'expliquer pourquoi je devrais m'en tenir à l'utilisation de propriétés pour tout, ou confirmer mon courant de pensées quant à la raison pour laquelle je devrais utiliser plus d'ivars et moins de propriétés uniquement là où c'est nécessaire? La réponse la plus convaincante de chaque côté recevra ma note.

EDIT: McNally intervient sur Twitter, disant : "Je pense que ma principale raison de rester avec les propriétés est: une façon de tout faire, qui fait tout (y compris KVC / KVO.)"

épologée
la source

Réponses:

5

Pouvez-vous m'expliquer un peu pourquoi je devrais m'en tenir à l'utilisation de propriétés pour tout, ou confirmer mon courant de pensées quant à la raison pour laquelle je devrais utiliser plus d'ivars et moins de propriétés uniquement en cas de besoin?

En ce moment, je pense qu'il est juste de dire que c'est surtout une question de style. Comme vous le dites, l'avantage de gestion de la mémoire des propriétés est moins important avec ARC. D'un autre côté, les "avantages" du retour à l'accès direct à l'ivar ne sont pas non plus très convaincants:

  1. Une déclaration @property est assez similaire à une déclaration ivar. Éviter la directive @synthesize ne semble pas être une grande victoire - nous ne parlons pas de beaucoup de code.

  2. La foo.somethingsyntaxe est sans doute bien meilleure que _something. La syntaxe d'accès aux propriétés est évidemment conçue pour ressembler et fonctionner comme la syntaxe à points de C pour accéder aux membres d'une structure. Être explicite sur l'objet auquel vous accédez (que ce soit selfou autre chose) est utile. (Certaines personnes - pas moi! - préconisent l' self->somethingaccès à l'ivar pour cette raison.) La principale convention de soulignement pour les ivars est correcte, mais elle n'est pas utilisée de manière cohérente par tous les codes Objective-C.

  3. Les propriétés semblent être un meilleur choix pour accéder aux données stockées dans d'autres objets de la même classe (ce qui est autorisé sous un accès "privé") et pour l'accès par des sous-classes (comme "protégé" de C ++). L'idée «propriétés == public» est donc quelque peu floue.

  4. Mon sentiment est que les propriétés étaient destinées à simplifier la gestion de la mémoire et à fournir d'autres avantages. Comme vous le dites, avec l'avantage de la gestion de la mémoire diminué, les propriétés semblent moins convaincantes.

Le chemin que vous avez choisi - revenir à l'accès direct à ivar pour les données internes - semble être un choix très raisonnable et il n'y a aucune raison évidente de changer de cap. Mais s'en tenir aux propriétés est également tout à fait raisonnable - les inconvénients ne sont pas importants, et il y a de beaux avantages comme la conformité KVO et un style d'accès aux membres plus cohérent.

Les propriétés n'étaient pas la dernière étape de l'évolution d'Objective-C, et je ne m'attends pas à ce que l'ARC le soit également. Je n'ai pas d'informations spécifiques, mais cela semble être une bonne supposition que des fonctionnalités supplémentaires puissent être ajoutées à un moment donné, ce qui rend les propriétés plus convaincantes ou moins. Nous devrons attendre et voir ce qui se passe.

Caleb
la source
1
Salut @Caleb, merci d'avoir pris le temps et d'avoir écrit un article solide. Je n'avais pas pensé à l'aspect KVO. Je suis en effet très curieux de savoir où Apple prend tout cela. ARC tel quel se sent comme l'un dans une série d'étapes. J'attendrai de voir si quelqu'un d'autre se soucie de peser sur le sujet, sinon considérez la question cochée.
épologue
1
@epologee Heureux de vous aider. Un autre élément à ajouter à la colonne plus pour les ivars est que vous pouvez les voir facilement dans le débogueur. Cela est également vrai pour les propriétés, si vous avez explicitement déclaré l'ivar que la propriété utilise. Les ivars synthétisés n'apparaissent pas dans le débogueur. (Je ne serais pas surpris de voir ce changement un jour prochainement.)
Caleb
-1

J'ai également réfléchi à cette question. À mon humble avis, seule l'utilisation de propriétés pour les accesseurs rend le code beaucoup plus lisible. Vous pouvez immédiatement voir quelles variables sont censées être accessibles au public. Et personnellement, toujours taper @property (...) devant une variable prend du temps.

Alex Boudreau
la source
Salut Alex, je pense que tu ferais mieux de répondre à des questions plus récentes ici sur SE. Je ne suis pas très d'accord avec l'argument qui prend du temps. Je n'écris pas de code qui me fait gagner du temps par écrit, j'aime écrire du code qui me fait gagner du temps à moi-même ou à quelqu'un d'autre pour le comprendre. Cela dit, le vote -1 n'était pas le mien. Ce serait bien que cette personne clarifie le vote.
epologee