Objective-C
Concept - Général
Surcouche au C
L'Objective-C ajoute l'orienté objet au langage C. Il est donc écrit en C et ajoute quelques éléments comme le YES/NO en valeur booléenne.
Définition d'une classe et des valeurs YES, NO et nil disponible sur Mac dans le fichier /usr/include/objc/objc.h :
typedef struct objc_class *Class;
typedef struct objc_object {
Class isa;
} *id;
...
#define YES ((BOOL)1)
#define NO ((BOOL)0)
#ifndef Nil
# if __has_feature(cxx_nullptr)
# define Nil nullptr
# else
# define Nil __DARWIN_NULL
# endif
#endif
#ifndef nil
# if __has_feature(cxx_nullptr)
# define nil nullptr
# else
# define nil __DARWIN_NULL
# endif
Typage
L'Objective-C est un langage à typage dynamique et statique. En effet, une partie des vérifications de type est réalisée à la compilation et une autre partie lors de l'exécution. L'Objective-C est aussi de typage faible, un int pouvant aussi être vu comme un short sans avoir à explicitement préciser au compilateur la conversion. Un exemple est donné dans le code suivant :
int a;
int b;
short c = a + b;
Les méthodes
Les méthodes (aussi appelées messages) ont une syntaxe particulière. Contrairement à d'autres langages, la lecture de la méthode permet de comprendre ce qu'elle fait. Une méthode est constituée d'un receveur (l'objet qui appelle la méthode) et d'un message (le nom de la méthode) le tout entre crochet pour délimiter l'appel.
[receiver message];
Voici quelques exemples de prototype et appel de méthodes avec et sans paramètres :
- (void)display;
[myRectangle display];
- (void)setWidth:(double)width;
[myRectangle setWidth:20.0];
- (void)setOriginX:(double)x y:(double)y;
[myRectangle setOriginX: 30.0 y: 50.0];
Les classes
Une classe se répartit sur deux fichiers. Le .h qui contient la définition de la classe, les attributs et les prototypes des méthodes. Le .m qui contient les implémentations de ces méthodes.
.h
@interface Object : NSObject <ObjectDelegate>
@property (strong, nonatomic) NSString *attribut;
-(void)methodPublic;
+(void)methodStatic;
@end
.m
#import "AppDelegate.h"
@implementation AppDelegate
-(void)methodPublic
{
NSLog(@"public %@", _attribut);
}
+(void)methodStatic
{
NSLog(@"static");
}
@end
Concept - Protocol
Introduction
Nous allons étudier dans cette partie le concept du protocole en Objective-C.
En théorie
L'objectif du protocole est de se détacher de l'implémentation d'une méthode. C'est à dire, laisser à une autre classe le soin d'implémenter cette méthode tout en restant l'appeleur de celle-ci. Cela revient à définir une interface en Java par exemple.
En pratique - Déclaration
Il faut tout d'abord déclarer la classe déléguée dans le .h de la classe :
@protocol DetailDelegate
-(void)methodDelegate:(NSString*)plop;
@end
On ajoute par la suite la référence au protocole dans la classe :
@property (strong, nonatomic) id<DetailDelegate> delegate;
Enfin on l'utilise lors de l'implémentation d'une méthode de la classe :
- (void)callDelegate
{
if (_delegate) {
NSLog(@"Delegate call from %p", self);
[_delegate methodDelegate:@"Youpi"];
}
}
Il est important de noter qu'il est possible qu'il n'y ait pas de délégué. C'est pour cela qu'il faut toujours tester la référence de la délégation.
En pratique - Implémentation
Nous allons maintenant voir comment implémenter une méthode d'un protocole.
Dans la classe où l'on souhaite implémenter une méthode déléguée, on ajoute la délégation.
@interface MasterViewController : UITableViewController <DetailDelegate>
Lors de l'instanciation de l'objet, on spécifie la classe en tant que que déléguée :
DetailViewController *d = [[DetailViewController alloc] init];
[d setDelegate:self]; // ou d.delegate = self;
Enfin on implémente la méthode :
- (void)methodDelegate:(NSString *)plop
{
NSLog(@"Call by %p with value %@", self, plop);
}
Concept - Sub-Classing
Introduction
Nous allons étudier dans cette partie le concept du sub-classing (aussi appelé Category) en Objective-C.
En théorie
Lorsqu'un objet est fourni en tant que librairie, il n'est plus modifiable. Cependant, il se peut que l'on souhaite ajouter une méthode qui n'ait pas été prévue lors de l'implémentation d'une librairie. C'est dans ce but là qu'a été pensé le sub-classing.
En pratique - Déclaration
Pour notre démonstration, nous allons ajouter une méthode à l'objet NSArray.
Premièrement, il faut créer une classe portant le nom de NSArray mais ayant un sous-nom stipulant ce que l'on souhaite ajouter :
@interface NSArray (OtherMethod)
- (void)methodAdded:(BOOL)isAdded;
@end
Avec son implémentation :
#import "NSArray+OtherMethod.h"
@implementation NSArray (OtherMethod)
- (void)methodAdded:(BOOL)isAdded
{
NSLog(@"Method is added ? %d", isAdded);
}
@end
A ce stade, nous venons de créer un sous-objet de NSArray contenant la méthode methodAdded.
En pratique - Utilisation
Une fois la sous-classe créée, nous allons maintenant l'utiliser. Pour cela, il suffit d'ajouter le header correspondant à la sous-classe et de créer un objet NSArray. Notre méthode sera reconnnue comme incluse dans les méthodes utilisables par l'objet NSArray. Ainsi, nous n'avons plus besoin de créer de MyNSArray héritant de NSArray.
Nous allons ajouter un NSArray dans notre méthode délégué de tout à l'heure.
#import "NSArray+OtherMethod.h"
@interface MasterViewController : UITableViewController <DetailDelegate>
- (void)methodDelegate:(NSString *)plop
{
NSArray *array = [[NSArray alloc] init];
[array methodAdded:YES];
NSLog(@"Call by %p with value %@", self, plop);
}
@end