2010-11-19 3 views
2

Dans mon projet j'ai 3 classes, appelons-les Apple, Orange et Pear. Apple et Orange ont toutes deux des propriétés de délégué.XCode avertissement incorrect "n'implémente pas le protocole X"


Ils définissent tous les deux des protocoles dans leur fichier d'en-tête appelé AppleDelegate et OrangeDelegate.
Ils ont chacun initializers avec des signatures similaires:

- (id)initWithDelegate:(id<AppleDelegate>)delegate 
- (id)initWithDelegate:(id<OrangeDelegate>)delegate 

Pear met en œuvre OrangeDelegate et est défini comme suit:

@interface Pear : NSObject <OrangeDelegate> 

Pear A l'intérieur, je fais cet appel:

Orange *anOrange = [[[Orange alloc] initWithDelegate:self] autorelease]; 

que les résultats dans cet avertissement de compilateur:

Class 'Pear' does not implement the 'AppleDelegate' protocol 

Il me semble que le compilateur ne reconnaît pas les protocoles dans les initialiseurs. En d'autres termes, il ne reconnaît que cette signature pour les deux:

- (id)initWithDelegate:(id)delegate 

Parce que quand je clique sur « Jump To Définition » sur le initialiseur en poire, il apporte à la fois des cours en option.

Est-il possible de corriger cet avertissement en plus de renommer mes méthodes?

+0

c'est bizarre, vous n'avez jamais assigné Pear à être un délégué de la pomme, quelque chose doit être éteint dans vos défenses je pense – Daniel

+0

@Daniel - C'est ce que je pensais, mais je suis sûr que ce n'est pas le cas. Je viens d'ajouter Apple et les avertissements sont apparus. Les deux Orange et Poire existaient avant cela, et compilé sans avertissements. Ni Orange ni Pear ont été modifiés quand j'ai ajouté Apple, mais soudainement ils ont commencé à lancer des avertissements. – DougW

Répondre

3

Le problème est que 'alloc' est une méthode héritée de NSObject, définie pour retourner le type 'id'. Donc, ce qui suit:

[Orange alloc] 

Évalue un objet de type 'id'. Lorsque vous appelez ensuite initWithDelegate sur cet objet, le compilateur ne connaît pas le type et, dans ce cas, devine le type incorrect. Ainsi, vous pouvez éliminer l'avertissement avec:

Orange *anOrange = [[(Orange *)[Orange alloc] initWithDelegate:self] autorelease]; 

Donc, en gros, c'est parce que les constructeurs ne sont pas une caractéristique de niveau linguistique en Objective-C, seulement une convention.

EDIT: voir ci-dessous; Je suppose une autre solution serait d'ajouter:

+ (Orange *)alloc; 

Pour Orange, ce qui serait rien de plus compliqué que:

+ (Orange *)alloc 
{ 
    return [super alloc]; 
} 

Je suppose qu'il est en partie une décision de conception - devraient les classes responsables de savoir que leurs méthodes constructeur peuvent entrer en conflit avec les noms d'autres classes ou les fichiers qui importent plusieurs définitions de classe avec les mêmes constructeurs sont responsables de la désambiguïsation. Bien que le simple aspect de la syntaxe puisse être le facteur décisif.

+0

Ah, ouais c'est logique. J'ai trouvé que le fait de lancer self (id) élimine également l'avertissement. L'un ou l'autre est un peu boiteux et moche, mais on dirait que c'est ça ou qu'on renomme les initialiseurs.Merci. – DougW

+0

Après y avoir réfléchi un peu plus longtemps (je n'ai jamais vu de conseil sur ce problème, je réponds simplement à partir des principes), je suppose que vous pouvez également surcharger init au lieu de simplement hériter de NSObject. J'ai modifié cela dans ma réponse, car il était plus facile de dire avec le code source. – Tommy

Questions connexes