2010-11-19 11 views
2

In meinem Projekt habe ich 3 Klassen, nennen wir sie Apple, Orange und Birne.XCode falsche Warnung "implementiert das X-Protokoll nicht"

Apple und Orange haben beide Delegateigenschaften.
Beide definieren Protokolle in ihrer Header-Datei namens AppleDelegate und OrangeDelegate.
Sie haben jeweils initializers mit ähnlichen Signaturen:

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

Pear implementiert OrangeDelegate und ist wie folgt definiert:

@interface Pear : NSObject <OrangeDelegate> 

Innen Birne, ich diesen Anruf:

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

Das Ergebnis in diesem Compiler Warnung:

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

Es scheint mir, dass der Compiler die Protokolle in den Initialisierern nicht erkennt. Mit anderen Worten, erkennt es nur diese Signatur für beide:

- (id)initWithDelegate:(id)delegate 

Denn wenn ich „Jump To Definition“ auf dem Initialisierer in Pear klicken, bringt es beiden Klassen als Optionen.

Gibt es eine Möglichkeit, diese Warnung zu korrigieren, abgesehen von der Umbenennung meiner Methoden?

+0

das ist seltsam, Sie nicht zuweisen Pear, um ein Apple-Delegierter sein, etwas muss in Ihren Entscheidungen sein Ich denke, – Daniel

+0

@Daniel - Das ist, was ich dachte, aber ich bin mir sicher, es ist nicht. Ich habe gerade Apple hinzugefügt und die Warnungen erschienen. Sowohl Orange als auch Birne existierten davor und wurden ohne Warnungen zusammengestellt. Weder Orange noch Pear wurden modifiziert, als ich Apple hinzufügte, aber plötzlich begannen sie, Warnungen zu werfen. – DougW

Antwort

3

Das Problem ist, dass "Alloc" eine Methode ist, die von NSObject geerbt wird, definiert, um den Typ 'ID' zurückzugeben. Also folgendes:

[Orange alloc] 

Bewertet zu einem Objekt vom Typ 'id'. Wenn Sie dann initWithDelegate für dieses Objekt aufrufen, kennt der Compiler den Typ nicht und nimmt in diesem Fall den falschen Wert an. So können Sie die Warnung mit beseitigen:

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

Also, im Grunde ist es, weil Konstrukteurs-Funktion nicht ein Sprachniveau ist in Objective-C, nur eine Konvention.

EDIT: siehe unten; Ich denke, eine andere Lösung wäre hinzuzufügen:

+ (Orange *)alloc; 

nach Orange, die nichts wäre komplizierter als:

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

Ich denke, es ist zum Teil eine Entscheidung Design - sollte Klassen verantwortlich sein zu wissen, dass ihre Konstruktormethoden können mit den Namen anderer Klassen kollidieren oder sollten Dateien, die mehrere Klassendefinitionen mit denselben Konstruktoren importieren, für die Begriffsklärung verantwortlich sein. Obwohl das einfache Aussehen der Syntax der entscheidende Faktor sein kann.

+0

Ah, ja das macht Sinn. Ich habe festgestellt, dass Casting Self to (ID) auch die Warnung eliminiert. Entweder ist man irgendwie lahm und hässlich, aber es sieht so aus, als würde man die Initialisierer umbenennen.Vielen Dank. – DougW

+0

Nachdem ich einen Moment darüber nachgedacht habe (ich habe noch nie einen richtigen Rat zu diesem Thema gesehen, ich antworte nur von den ersten Prinzipien), könnte man auch init überschreiben, anstatt es nur von NSObject erben zu lassen. Ich habe das in meiner Antwort bearbeitet, da es am einfachsten war, mit Quellcode zu sagen. – Tommy

Verwandte Themen