74 votes

Comment étendre les protocoles / délégués en Objective-C ?

Si je veux étendre une classe comme AVAudioPlayer, quelle est la meilleure façon d'ajouter une autre méthode à AVAudioPlayerDelegate ?

Dois-je en faire une catégorie, dois-je l'étendre ?

Si je l'étend, dois-je également m'assurer d'écraser le délégué actuel getter/setter ? Comment puis-je étendre le protocole ?

Ce qui suit me donne des erreurs

@protocol AudioTrackDelegate : AVAudioPlayerDelegate {
    - (void)foo;
}
@end

@interface AudioTrack : AVAudioPlayer {
}
@end

134voto

rpetrich Points 25769

La syntaxe pour créer un protocole qui implémente un autre protocole est la suivante :

@protocol NewProtocol <OldProtocol>
- (void)foo;
@end

Si vous voulez appeler une méthode dans NewProtocol sur un pointeur tapé comme OldProtocol vous pouvez soit appeler respondsToSelector :

if ([object respondsToSelector:@selector(foo)])
    [(id)object foo];

Ou définir les méthodes de stub comme une catégorie sur NSObject :

@interface NSObject (NewProtocol)
- (void)foo;
@end
@implementation NSObject (NewProtocol)
- (void)foo
{
}
@end

0 votes

Si je crée un protocole qui implémente un autre protocole... Y a-t-il quelque chose d'autre que je doive faire pour m'assurer que les méthodes 'OldProtocol' soient activées ? parce que pour moi, le nouveau protocole est activé mais tous les protocoles existants ne le sont plus...

10 votes

Un protocole n'a pas de méthodes, il a des définitions de méthodes ; c'est-à-dire qu'il décrit le nom, les arguments et les types de retour qu'une classe doit avoir pour être considérée comme "conforme" audit protocole. Par votre commentaire/question, je parie que vous oubliez d'appeler [super setDelegate:value] dans votre -setDelegate :

0 votes

En utilisant cette approche, vous n'exposez pas les méthodes du nouveau protocole, jetez un coup d'oeil à ma réponse pour une méthode plus propre.

10voto

Rappelez-vous qu'un protocole n'ajoute aucun code à l'application compilée - il ne fait qu'imposer le fait que votre classe doit implémenter les méthodes pour être considérée comme "conforme" au protocole. Une bonne utilisation de ce protocole serait de générer un groupe de classes ayant toutes le même mode de fonctionnement : <printable> o <serialized> etc. Vous pourriez donc créer un <plays> par exemple :

@protocol plays
    - (void) play;
    - (NSString *) type;
@end

Et ensuite une classe qui se conforme à <plays> DOIT mettre en œuvre le play y type méthodes. Si ce n'est pas le cas, le compilateur émet un avertissement mais compile quand même la classe. Dans votre code, vous vérifiez si un objet se conforme à un protocole avec le code suivant :

if ([obj conformsTo: @protocol(plays)]) {
    [obj play];
}

Une catégorie ajoute en fait de nouvelles méthodes de façon dynamique à votre classe. Ces méthodes sont globalement accessibles au runtime comme des sélecteurs et peuvent être appelées par leur nom comme dans @selector(foo) y [object foo:bar];

Le but d'une catégorie est d'ajouter un nouveau code spécial à une classe même si vous n'avez pas le code source de cette classe. Il peut y avoir des problèmes de sécurité et vous pourriez créer des fuites de mémoire dans les classes, etc.

Dans votre cas peut-être, dans un fichier séparé AVAudioPlayerDelegate_TrackOps.m

#import "AVAudioPlayerDelegate.h"
@implementation AVAudioPlayerDelegate (TrackOps)

- (NSObject *) foo {
    // do foo stuff;
    return bar;
}

@end

En le plaçant dans une catégorie de NSObject fait que toutes les classes répondent à foo . Foo peut être une méthode autonome Objc_perform_selector(@selector(foo)) également.

Bottom Line : utiliser une catégorie pour ajouter une méthode rapide à une classe, des protocoles pour faire respecter les implémentations de méthodes, et des sous-classes pour spécifier les méthodes. l'implémentation des méthodes, et des sous-classes pour spécialiser des classes existantes (comme l'ajout de variables membres ou de nouvelles fonctionnalités majeures). Les catégories peuvent également être utilisées pour remplacer une méthode ou deux lorsqu'une sous-classe n'est pas nécessaire ou souhaitée, mais généralement, si vous voulez ajouter une fonctionnalité à une classe, vous créez une sous-classe. Pour plus d'exemples, d'idées, et d'autres informations générales sur ce sujet, il y a toujours la page Introduction d'Apple à Objective-C

0 votes

Pouvez-vous nous expliquer comment ajouter une catégorie à un protocole ? Je pense que quelque chose ne va pas dans la syntaxe de ce que vous avez écrit. Merci.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X