Question

J'aimerais qu'un objet variable d'instance adopte un protocole.

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

Par exemple, j'aimerais que mon objet Layer adopte le <CocosNodeOpacity> afin d'obtenir les méthodes

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

gratuitement. La syntaxe indiquée 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.

Était-ce utile?

La solution

S'il s'agit de tout le code que vous avez créé, la meilleure façon de le faire est probablement de faire en sorte que la classe Layer adopte elle-même le protocole plutôt que la variable.

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

Un avantage clé de cette approche est que le compilateur vérifie si vous avez implémenté toutes les méthodes requises dans le protocole lors de la compilation, ce qui correspond généralement à vos souhaits. Ajouter les méthodes au même endroit que le reste de l'implémentation de classe standard est plus facile à comprendre (pas de chasse pour trouver d'où vient le code magique) et moins fragile que d'utiliser des catégories (ajouter 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 je dois y ajouter des méthodes, telles que l'ajout de méthodes à du code tiers (à source fermée).

Si vous ne contrôlez pas la source de id, vous devrez peut-être l'utiliser à la place lorsque vous déclarerez votre ivar:

Layer<CocosNodeOpacity> *content;

Notez que l’adoption d’un protocole vous permet de taper statiquement des variables avec un type de classe et d’obtenir des avertissements de compilation si les méthodes ne sont pas présentes. Cependant, vous n'obtenez pas les méthodes & "Gratuites" & ";", Car vous devez toujours les implémenter. Néanmoins, une utilisation judicieuse des protocoles et du typage statique peut rendre votre code plus robuste et & "Fail-fast &"; que d'utiliser <=> comme type pour tout. Vous devez être félicité pour ne pas prendre la solution de facilité. : -)

Pour plus de détails sur les protocoles (y compris les méthodes obligatoires et facultatives), voir cette réponse à une offre à commandes .

Autres conseils

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 si vous disiez & «Je garantis que, quel que soit l'objet, il utilise ces méthodes. &«;

Vous êtes assez proche de la syntaxe de votre premier bloc de code. Cela ressemblerait à quelque chose comme ça:

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

Toutefois, cela ne vous évite pas de devoir définir les méthodes d'opacité dans votre classe Layer. En utilisant le protocole, vous avez établi que votre classe disposerait de ces fonctions, mais vous ne les avez pas encore fournies. Vous aurez toujours besoin d'écrire le code pour eux.

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

Il existe une abondance de documentation pour les catégories ici sur le dépassement de capacité de la pile. Les docs Apple sont également très bons. Voici un article pour vous aider à démarrer:

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top