2009-08-05 7 views
4

J'ai une classe avec une propriété de délégué. Toute personne qui veut être un délégué doit se conformer à un protocole. J'ai défini tout comme ceci:Comment se conformer à un protocole self-made?

#import <UIKit/UIKit.h> 

@protocol TheDelegateProtocol; 

@interface MyClass : UIView { 
    id<TheDelegateProtocol> theDelegate; 
} 

@property (nonatomic, assign) id<TheDelegateProtocol> theDelegate; 


@end 


@protocol TheDelegateProtocol<NSObject> 
@required 

- (void)fooBarWithFoo:(CGFloat)foo; 
@end 

Maintenant, la chose folle est: J'ai une autre classe qui veut être le délégué. Donc, il est conforme à ce protocole, comme ceci:

#import <Foundation/Foundation.h> 

@class MyClass; // forward declaration. importet in implementation. 
@protocol TheDelegateProtocol; // need forward declaration here, right? 

@interface OtherClass : NSObject <TheDelegateProtocol> { 
    // ivars 
} 

@end 

Je n'arrive pas à faire fonctionner cela. Il dit: "Aucune définition de protocole 'TheDelegateProtocol' trouvé". Eh bien, ce protocole est défini dans MyClass, et j'importe MyClass dans l'implémentation. Une idée de ce qui ne va pas?

A trouvé quelque chose: Dans une méthode où j'essaie d'assigner le protocole, il me dit que OtherClass n'est pas conforme au protocole. Mais ça le fait! Ça n'a aucun sens. J'ai également ajouté la méthode de protocole dans l'en-tête ....

Répondre

0

Est-ce un avertissement? parce que parfois ça fait ça quand vous avez des références circulaires et des trucs, et ça devient confus, mais en réalité c'est ok, avez-vous essayé de le lancer pour voir si ça fonctionne? Dans mon projet j'ai un tas d'avertissement sur les protocoles non trouvés, ils sont là et ça fonctionne bien ... Ce que vous pouvez faire pour vous débarrasser de l'avertissement est de définir le protocole en dehors de la classe sur un autre fichier. Vous n'avez pas vraiment besoin de la déclaration forward, vous pouvez simplement faire # import du fichier .h défini dans

+2

Ce n'est pas une bonne habitude d'ignorer les avertissements, quels qu'ils soient ... –

4

Mettez la définition du protocole dans un fichier séparé. #import ce fichier dans un fichier d'en-tête qui en a besoin.

4

Je pense que vous devez #import le fichier d'en-tête qui définit le protocole. Comment le compilateur peut-il savoir quelles méthodes sont disponibles sans lui?

Si vous utilisez une autre classe (par exemple, en tant que ivar ou en tant que paramètre d'une méthode), vous pouvez utiliser une déclaration forward. Mais si vous sous-classe alors vous devez #import.

+0

Comment est-ce que je pourrais mettre cette définition de protocole dans un propre fichier? Aurais-je juste un fichier .h, mais pas de fichier .m pour cela? Le fichier .m n'aurait aucun sens pour un protocole. –

+0

Oui, c'est vrai. –

0

Vos deux classes diffèrent dans leur utilisation du protocole. MyClass n'implémente pas le protocole, il a un attibute qui est un pointeur vers une classe qui implémente le protocole. OtherClass doit implémenter le protocole.

OtherClass doit avoir disponible avant que son interface ne définisse tous les détails des protocoles, des interfaces et des classes dont il hérite. Vous avez donc besoin que le protocole dans un en-tête soit # importé dans OtherClass.h

MyClass a juste besoin de savoir que le protocole existe dans son interface.

Remarque sur le sous-classement de réponses de Stephen est le cas où vous ne pouvez pas utiliser les déclarations de classes forward. (Dans l'exemple OtherClass est une sous-classe de NSObject)

+0

Oui, la sous-classe était le mauvais mot. J'ai reformulé ma réponse pour clarifier ce que je voulais dire. –

3

L'avertissement du compilateur est correct. OtherClassn'est pas est conforme au protocole car il ne déclare pas la méthode fooBarWithFoo requise attendue par le protocole.

Avez-vous essayé de cette façon?

#import "MyClass.h" 

@interface OtherClass : NSObject <TheDelegateProtocol> { 
    // ivars 
} 

- (void)fooBarWithFoo:(CGFloat)foo; // <<< missing bit 

@end 
1

Il n'a pas besoin de déclarer les méthodes pour se conformer au protocole. Il suffit de les implémenter dans le fichier .m.