Objective-C : @Protocol & delegate

xcodeIl est difficile de parler des delegates sans parler des protocoles, et réciproquement. Un protocol, c’est un contrat d’implémentation qu’une class s’engage à respecter. Il s’agit de l’équivalent des Interfaces en JAVA.

@Protocol

Un protocol s’écrit de la façon suivante:

@protocol MyProtocol

- (void)helloWorld;

@end

Et l’implémentation d’un protocol par une classe s’indique dans sa déclaration:

@interface MyClass <MyProtocol>

@end

Il faut bien sûr ensuite que la class implémente sa méthode (dans le fichier d’implémentation).

Les protocols sont très utilisés en Objective-C, notamment lors de l’utilisation du mécanisme de délégation.

Les Delegates

Si vous développer en Objective-C, vous êtes forcément déjà tombés sur ce mot, par exemple lors de l’utilisation d’UITableView.

Le principe des delegates est de déléguer (sans blague !) un comportement à un objet tiers. Pour cela, l’objet qui déléguera ce compretement stockera une delegate du type id. Pour être sûr que la delegate soit en mesure de répondre à l’appel, il est souvent déclarer de la façon suivante :

@class MyClass

@property (nonatomic, retain) id<MyProtocol> delegate;

@end

En général, le protocol que doit implémenter une delegate est déclaré dans le .h de la class. On se retrouve donc avec 4 fichiers:

– MyClass.h

// Déclaration du protocol que devra implémenter la delegate
@protocol MyClassDelegate
- (void)hello;
@end

// Déclaration de l'interface de la class
@interface
@property (nonatomic, retain) id<MyClassDelegate> delegate;
@end

MyClass.m

// Impémentation de MyClass qui délègue un appel
@implementation MyClass
- (void)hello {
    if (delegate != nil) {
        [delegate hello];
    }
}
@end

MyObject.h

@interface MyObject id<MyProtocol>
@end

MyObject.m

@implementation

- (void)init {
    MyClass *mc = [[MyClass alloc] init];
    mc.delegate = self;
}

- (void)hello {
    // L'implémentation peut-être vide mais la méthode doit être définie.
}
@end

(Les #import ne sont pas présents pour plus de clarté).

Pour finir, il arrive que le protocol MyProtocol utilise un objet de type MyClass. Comme cette class est définie après lui, le compilateur s’y perd un peu et il faut lui indiquer qu’il s’agit d’une class qui sera déclarée plus tard. Voici un exemple:

– MyClass.h

// On prévient que MyClass sera défini plus tard
@class MyClass;

// Déclaration du protocol que devra implémenter la delegate
@protocol MyClassDelegate
- (void)hello:(MyClass *)myClass;
@end

// Déclaration de l'interface de la class
@interface
@property (nonatomic, retain) id<MyClassDelegate> delegate;
@end

MyClass.m

// Impémentation de MyClass qui délègue un appel
@implementation MyClass
- (void)hello {
    if (delegate != nil) {
        [delegate hello:self];
    }
}
@end

Publié par

gcko

#iOS developer at @applydia, former #Epitech student, «I'm am currently making your smartphone smarter»