2009-08-05 3 views
4

Ich habe eine Klasse mit einer Delegat-Eigenschaft. Wer Delegierter sein will, muss sich an ein Protokoll halten. Ich definiert alles wie folgt aus:Wie kann man einem selbst erstellten Protokoll entsprechen?

#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 

Nun ist die verrückte Sache ist: Ich habe eine andere Klasse, die der Delegierte sein will. So entspricht es diesem Protokoll, wie folgt:

#import <Foundation/Foundation.h> 

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

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

@end 

Ich kann das nicht zur Arbeit bekommen. Es heißt: "Keine Definition des Protokolls 'TheDelegateProtocol' gefunden". Nun, dieses Protokoll ist in MyClass definiert, und ich importiere MyClass in der Implementierung. Irgendeine Idee, was ist da falsch?

Etwas herausgefunden: In einer Methode, wo ich versuche, das Protokoll zuzuordnen, sagt es mir, dass OtherClass nicht dem Protokoll entspricht. Aber es tut! Das macht keinen Sinn. Ich fügte auch die Protokollmethode im Titel hinzu ....

Antwort

0

Ist dies eine Warnung? denn manchmal macht es das, wenn du Zirkelverweise und Zeug hast, und es wird verwirrt, aber in Wirklichkeit ist es in Ordnung, hast du versucht, es auszuführen, um zu sehen, ob es funktioniert? In meinem Projekt habe ich eine Reihe von Warnungen über Protokolle nicht gefunden, sie sind aber da und es funktioniert gut ... Was Sie tun können, um die Warnung loswerden ist versuchen, das Protokoll außerhalb der Klasse in einer anderen .h-Datei zu definieren. Sie brauchen auch nicht die Forward-Deklaration, Sie können einfach #import der .h-Datei ausführen, die in

+2

Es ist nicht großartig, Warnungen zu ignorieren, was auch immer sie sind ... –

4

definiert ist Setzen Sie die Definition des Protokolls in eine separate Datei.

#importiere diese Datei in eine Header-Datei, die sie benötigt.

4

Ich denke, Sie müssen #import die Header-Datei, die das Protokoll definiert. Wie kann der Compiler wissen, welche Methoden ohne ihn verfügbar sind?

Wenn Sie eine andere Klasse verwenden (d. H. Als ein Ivar oder als Parameter für eine Methode), können Sie eine Forward-Deklaration verwenden. Aber wenn Sie Unterklasse dann müssen Sie #import.

+0

Wie würde ich diese Protokolldefinition in eine eigene Datei schreiben? Würde ich nur eine .h-Datei haben, aber keine .m-Datei dafür? Die .m-Datei würde für ein Protokoll keinen Sinn ergeben. –

+0

Ja, das stimmt. –

0

Ihre zwei Klassen unterscheiden sich in ihrer Verwendung des Protokolls. MyClass implementiert das Protokoll nicht, es hat eine Eigenschaft, die ein Zeiger auf eine Klasse ist, die das Protokoll implementiert. OtherClass sollte das Protokoll implementieren.

OtherClass muss verfügbar sein, bevor seine Schnittstelle alle Details der Protokolle, Schnittstellen und Klassen definiert hat, von denen es erbt. Daher brauchen Sie das Protokoll in einer Kopfzeile, die in OtherClass.h importiert werden soll.

MyClass muss nur wissen, dass das Protokoll in seiner Schnittstelle existiert.

Hinweis auf Stephen's Antwort Unterklassen ist der Fall, dass Sie nicht Vorwärtsdeklarationen von Klassen verwenden können. (Im Beispiel ist OtherClass eine Unterklasse von NSObject)

+0

Ja, Unterklasse war das falsche Wort. Ich habe meine Antwort neu formuliert, um klarer zu machen, was ich meinte. –

3

Die Warnung des Compilers ist korrekt. OtherClassentspricht nicht dem Protokoll, da nicht die erforderliche fooBarWithFoo-Methode deklariert, die das Protokoll erwartet.

Haben Sie es auf diese Weise versucht?

#import "MyClass.h" 

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

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

@end 
1

Er muss die Methoden nicht deklarieren, um dem Protokoll zu entsprechen. Er muss sie nur in der .m-Datei implementieren.