2

Je suis confus par ceci: http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/AccessorConventions.html#//apple_ref/doc/uid/20002174-178830-BAJEDEFBTableau KVC: getters vs accesseurs indexés?

Supposant

@interface Office : NSObject { 
    NSMutableArray *employees; 
} 
  1. Quel est l'avantage de mettre en œuvre les accesseurs de collecte?

  2. Comment est [anOffice countOfEmployees] mieux que [[anOffice employees] count]?

  3. Les fixations dépendent-elles des accesseurs de collection ou puis-je les supprimer complètement? Ils me semblent redondants puisque j'utilise un vrai objet tableau. Je peux comprendre comment ils seraient nécessaires si les employés n'étaient pas un NSMutableArray et n'ont pas implémenté quelque chose comme une méthode de compte elle-même.

  4. Je suis également absolument perplexe par pourquoi utiliserait mutableArrayValueForKey:@"employees" pour récupérer la propriété employees à la place pour simplement valueForKey:@"employees".

Merci!

Répondre

3

Vous pouvez renoncer aux accesseurs de collection; ils ne sont pas requis. Mais ils rendent les choses beaucoup plus faciles. Une des raisons de les avoir, y compris countOfEmployees, est l'efficacité: La méthode employees peut renvoyer une copie de l'objet tableau (en particulier puisque la copie de l'Office est mutable, donc l'Office ne voudrait pas que d'autres objets mutent la matrice sous it), mais si vous avez seulement besoin de connaître le nombre ou d'accéder à un objet à un index spécifique, vous n'avez pas besoin d'une copie.

L'autre raison est lorsque l'expéditeur veut muter la propriété.

  • valueForKey: appellera employees, qui renvoie habituellement une copie immuable.
  • Renvoyer une copie mutable n'aiderait pas, puisque la mutation de ce tableau serait la mutation de la copie, pas l'original à travers la propriété.
  • Le retour du tableau d'origine n'autorisera pas l'expéditeur à provoquer des notifications KVO pour ses modifications. Par conséquent, aucune observation de la propriété ne permettra de connaître ces modifications. Cela signifie que les valeurs affichées dans votre interface utilisateur seront périmées (ne seront pas mises à jour).

mutableArrayValueForKey: retourne un tableau faux qui envoie des messages de mutation (ou, si rien d'autre, employees et setEmployees: messages) à l'objet d'origine. Les messages Accesseur génèrent des notifications KVO. Par conséquent, tout ce qui observe la propriété suivra ces modifications, afin que votre interface utilisateur reste à jour.

Bien sûr, vous pouvez simplement envoyer les messages d'accesseur vous-même. mutableArrayValueForKey: est principalement pour si vous souhaitez apporter des modifications à une propriété qui n'est pas connue au moment de la compilation; NSArrayController est, vraisemblablement, un utilisateur de cette méthode. Il est peu probable que vous ayez besoin d'utiliser mutableArrayValueForKey: dans une application régulière, et envoyer des messages d'accesseur vous-même est, à mon avis, plus facile à lire.

Tout cela vaut également pour Office, lorsqu'il mute son propre tableau. Il pourrait juste parler à son objet tableau directement, mais cela ne causerait pas de notifications KVO, donc rien d'autre ne saurait que la valeur de la propriété avait changé. Vous pouvez poster les notifications KVO vous-même à chaque changement, mais c'est un problème et facile à oublier. Les accesseurs de collection et mutableArrayValueForKey: sont deux solutions à ces problèmes: Chaque accès est une ligne de code unique qui provoquera des notifications KVO.

+0

Pourquoi [[anOffice employees] insertObject: ...] n'est pas KVC? Vraisemblablement, les objets observant le tableau des employés devraient recevoir une notification quand cela est appelé. Deuxièmement, pourquoi recommandez-vous aux employés getter de retourner une copie immuable? Merci Peter. – Alexandre

+2

@Alexandre: Je ne sais pas pourquoi vous présumeriez cela. Ce n'est pas correct. La mutation d'un tableau ne crée aucune notification KVO - le tableau ne sait pas qui l'observe et s'en moque. Les notifications de modification sont émises par le contrôleur responsable du tableau, et elles ne se produiront pas si vous passez derrière le contrôleur et si vous mutez directement le tableau. – Chuck

+1

Le getter ne doit pas renvoyer le tableau d'origine, car l'appelant pourrait alors faire muter le tableau derrière le contrôleur, ce qui causerait des problèmes. Si vous renvoyez une copie mutable, l'appelant peut muter ce tableau, ainsi '[[unofficiel] insertObject: ...]' ne tombera pas en panne, mais il ne mutera pas non plus les employés du bureau, car il mute la copie. Le code qui ne fait pas ce qu'il semble faire est mauvais. Renvoyer une copie immuable garantit que l'appelant ne peut pas muter le tableau d'origine ni croire à tort qu'il le fait. –

Questions connexes