I. Principe▲
Dans ce modèle de conception, chaque propriété d'un objet est identifiée par un nom, la clef.
Les méthodes de consultation et de modification de la valeur d'une propriété doivent suivre des conventions de nom pour que la classe respecte le modèle de conception KVC (1).
Ce modèle est largement documenté par Apple sur son site de développement.
II. Principes de mise en œuvre▲
Il est extrêmement simple de respecter ce modèle de conception pour au moins une raison : les conventions sont tout à fait naturelles et s'apprennent en même temps que le langage Objective-C.
On peut résumer la conformité en quatre points :
Nom de la propriété |
UnePropriété |
Méthode de consultation (accessor) |
- (TYPE) unePropriete ; |
Méthode de modification (modifier) |
- (void) setUnePropriete : (TYPE) uneValeur ; |
Méthode de validation (2) |
- (BOOL) validateUnePropriete : (id*) valeurInOut error : (NSError **) erreurOut |
À l'exception de la méthode de validation (3) ces conventions ne seront pas sans rappeler quelques souvenirs à tous ceux qui connaissent Java et le modèle des JavaBeans.
Ces conventions correspondent tout à fait à celles définies pour les JavaBeans, à l'exception de la méthode d'accès qui pour des raisons évidentes de syntaxe est préfixée d'un get.
III. Exemple de mise en œuvre▲
À titre d'exemple il nous pouvons implémenter une classe Person avec deux propriétés :
- lastName pour le nom ;
- firstName pour le prénom.
L'interface de la classe sera la suivante :
@interface
Person : NSObject
{
@private
NSString
*
firstName;
NSString
*
lastName;
}
-
(
NSString
*
) firstName;
-
(
void
) setFirstName: (
NSString
*
) aFirstName;
-
(
NSString
*
) lastName;
-
(
void
) setLastName: (
NSString
*
) aLastName;
L'implémentation des méthodes d'accès et modification sur la propriété firstName sera la suivante :
-
(
NSString
*
) firstName
{
return
firstName;
}
-
(
void
) setFirstName: (
NSString
*
) aFirstName
{
if
(
aFirstName !=
firstName ) {
[aFirstName retain
];
[firstName release];
firstName =
aFirstName;
}
}
Le même modèle est utilisé pour l'implémentation des méthodes -(NSString*) lastName et -(void) setLastName :(NSString*) aName. En cas de doute, consultez l'implémentation fournie dans le projet joint à cet article.
IV. Protocole associé▲
Suivre des conventions de code est un bon point pour assurer la lisibilité de son code source, mais cette raison n'est bien évidemment pas la seule.
La vraie force des conventions de codage KVC est de permettre une manipulation générique des objets pour consulter et modifier les valeurs des propriétés. Cela permet à ce modèle de conception d'être l'un des principaux socles des API Cocoa avec le complément KVO (4) .
Les conventions de codage sont donc complétées par le protocole informel(5)NSKeyValueCoding.
Ce protocole est implémenté par la classe NSObject et offre des fonctions pour consulter, modifier et valider les valeurs des propriétés d'un objet.
Les deux principales méthodes sont les suivantes :
Service |
Signature |
---|---|
Consulter une valeur |
- (id)valueForKey :(NSString *)clef |
Modifier une valeur |
- (void)setValue :(id)valeur forKeyPath :(NSString *)chemin |
À ces deux méthodes s'ajoutent celles qui gèrent la validation d'une valeur, la modification et l'accès à un groupe de valeurs ou encore la gestion de valeurs modifiables.
V. Exemple d'utilisation du protocole NSKeyValueCoding▲
Le protocole NSKeyValueCoding utilise la réflexivité du langage Objective-C pour identifier les méthodes disponibles pour consulter et modifier les propriétés d'un objet.
On peut donc utiliser les méthodes valueForKey:clef et setValue:valeur forKeyPath:chemin en lieu et place des méthodes directement définies dans l'interface. Cela permet donc de manipuler les propriétés d'un objet sans pour autant en connaître l'interface exacte.
Notre programme d'exemple va utiliser le protocole en trois étapes :
- Consulter la valeur des propriétés d'un objet ;
- Modifier la valeur des propriétés d'un objet ;
- Consulter la valeur d'une propriété en utilisant un chemin complet plutôt qu'un nom seul.
Pour initialiser notre objet, notre exemple doit créer une instance et appeler les deux méthodes de modification :
Person *
author =
[[Person alloc] init];
[author setFirstName: @"Sylvain"
];
[author setLastName: @"Gamel"
];
Une fois cette instance prête, il est possible d'afficher les méthodes en utilisant valueForKey:clef.
NSLog
(
@"Author firstName %@"
,
[author valueForKey:@"firstName"
]);
NSLog
(
@"Author lastName %@"
,
[author valueForKey:@"lastName"
]);
La modification des valeurs des propriétés est réalisée par la méthode setvalue:valeur forKey:clef.
[author setValue:@"Steven"
forKey:@"firstName"
];
Mais le protocole ne se limite pas à la consultation d'une simple valeur de propriété. On peut aussi aller chercher la valeur d'une propriété à partir d'un chemin dans le graphe d'objets. Le chemin utilise la notation pointée classique comme dans l'exemple ci-dessous :
NSLog
(
@"Author firstName.length %@"
,
[author valueForKeyPath:@"firstName.length"
]);
VI. Conclusion▲
Et voilà un rapide tour d'horizon du modèle de conception Key Value Coding. Ce modèle est une première étape pour concevoir des classes qui soient des citoyennes de premier ordre avec Cocoa.
Car si en effet il est utile de pouvoir consulter et manipuler les valeurs des propriétés d'un objet, il est encore plus utile de pouvoir suivre les évolutions de ces valeurs. C'est tout l'objet du modèle Key Value Observing KVO. Un modèle qui fera l'objet d'un article spécifique très prochainement.
Vous pouvez récupérer le projet de l'exemple présenté dans cet article.