2009-06-23 5 views
2

J'aimerais qu'un objet de variable d'instance adopte un protocole.Objective-C: Protocoles

@interface GameScene : Scene <AVAudioPlayerDelegate> { 
@private 
    Layer *content <CocosNodeOpacity>; 
} 

Par exemple, j'aimerais mon objet couche d'adopter le <CocosNodeOpacity> pour que je puisse obtenir gratuitement les méthodes

-(GLubyte) opacity; //and 
-(void) setOpacity: (GLubyte) opacity; 

. La syntaxe ci-dessus n'est pas valide. Est-il possible d'y parvenir sans créer un nouveau fichier d'implémentation et créer un objet personnalisé? Merci.

Répondre

5

Si ceux-ci sont tous les codes que vous avez créé, la meilleure façon de le faire est sans doute de faire la classe elle-même Layer adopter le protocole, plutôt que la variable.

@interface Layer : NSObject <CocosNodeOpacity> { ... } 

Un des principaux avantages de cette approche est que le compilateur vérifiera si vous avez mis en œuvre toutes les méthodes requises dans le protocole au moment de la compilation, qui est généralement ce que vous voulez. L'ajout des méthodes au même endroit que le reste de l'implémentation de la classe standard est plus facile à comprendre (pas de recherche pour trouver le code magique) et moins fragile que l'utilisation de catégories (l'ajout de la même méthode via différentes catégories peut entraîner un comportement indéfini) . En règle générale, je n'utilise les catégories que lorsque a, comme l'ajout de méthodes au code tiers (source fermée).

Si vous ne contrôlez pas la source de Layer, vous devrez peut-être utiliser ce lieu lorsque vous déclarez votre Ivar:

Layer<CocosNodeOpacity> *content; 

Notez que l'adoption d'un protocole vous permet de taper statiquement les variables avec un type de classe et obtenez des avertissements de compilation si les méthodes ne sont pas présentes. Cependant, vous n'obtenez pas les méthodes «gratuitement», car vous devez toujours les implémenter.Pourtant, l'utilisation judicieuse des protocoles et le typage statique peuvent rendre votre code plus robuste et «fail-fast» que d'utiliser id comme type pour tout. Vous devez être félicité pour ne pas simplement prendre la voie facile. :-)

Pour plus d'informations sur les protocoles (y compris les méthodes obligatoires et facultatives), voir this SO answer.

2

Un protocole en Objective-C est similaire à une interface en Java. Le protocole définit un ensemble de fonctions et agit comme un contrat. C'est comme dire "je garantis que quel que soit cet objet, il a ces méthodes".

Vous êtes assez proche de la syntaxe dans votre premier bloc de code. Il ressemblerait en fait quelque chose comme ceci:

@interface GameScene : Scene <AVAudioPlayerDelegate> { 
@private 
    Layer<CocosNodeOpacity> * content; 
} 

Cependant, cela ne vous sauve pas d'avoir à définir les méthodes d'opacité dans votre classe de couche. En utilisant le protocole, vous avez établi que votre classe aura ces fonctions, mais vous ne les avez pas réellement fournies. Vous aurez toujours besoin d'écrire le code pour eux.

Je pense que ce que vous cherchez est une catégorie Objective-C. Une catégorie fournit un moyen d'étendre la fonctionnalité de n'importe quelle classe en y ajoutant des méthodes lors de l'exécution. Ils sont possibles parce que Objective-C est un langage complètement dynamique. Si vous n'êtes pas l'auteur de la classe Layer et que vous ne pouvez pas facilement lui ajouter les méthodes d'opacité, une catégorie est le chemin à parcourir. Dans certains cas, les catégories sont extrêmement utiles - vous pouvez ajouter des méthodes aux classes intégrées, comme NSString et NSColor, sans avoir la source de classe existante.

Il y a beaucoup de documentation pour les catégories ici sur le débordement de pile. Les docs apple sont aussi très bons. Voici un article pour vous aider à démarrer:

http://macdevelopertips.com/objective-c/objective-c-categories.html

Questions connexes