@class
existiert, um zirkuläre Abhängigkeiten zu brechen. Angenommen, Sie haben die Klassen A und B.
@interface A:NSObject
- (B*)calculateMyBNess;
@end
@interface B:NSObject
- (A*)calculateMyANess;
@end
Hähnchen; Ei treffen. Dies kann niemals kompiliert werden, da die Schnittstelle von A davon abhängt, dass B definiert ist und umgekehrt.
Somit kann es behoben werden mit @class
:
@class B;
@interface A:NSObject
- (B*)calculateMyBNess;
@end
@interface B:NSObject
- (A*)calculateMyANess;
@end
@class
teilt dem Compiler effektiv mit, dass eine solche Klasse irgendwo existiert, und daher sind Zeiger, die deklariert wurden, um auf Instanzen dieser Klasse zu verweisen, vollkommen gültig. Sie konnten jedoch keine Methode für eine Instanzreferenz aufrufen, deren Typ nur als definiert ist, da @class
dem Compiler keine zusätzlichen Metadaten zur Verfügung stehen (ich kann mich nicht erinnern, ob die Aufrufsite wieder als Aufruf durch id
oder ausgewertet wird nicht).
In Ihrem Beispiel ist das @class
harmlos, aber völlig unnötig.
id
Bewertung zurückgegriffen.@class
ihre .h-Datei einfügen und dann die erforderlichen Header-Dateien in ihre .m-Datei importieren, während andere möglicherweise nur die .h-Datei in die aktuelle Klassen-Header-Datei importieren? Nur neugierig, danke. @bbum@class TestClass;
Dies erklärt lediglich "Klasse TestClass wird definiert".
In diesem Fall (dem, den Sie eingefügt haben) hat dies keinerlei Auswirkungen, daher sind diese gleich.
Wenn Sie jedoch ein Protokoll definieren möchten, das Ihren Klassennamen verwendet (z. B. als Parametertyp, der an die Delegierung übergeben wird), müssen Sie dies
@class TestClass
vor der Protokolldefinition deklarieren , da Ihre Klasse noch nicht definiert ist.Wenn Sie Ihren Klassennamen angeben müssen, bevor die Klassendefinition erstellt wird, müssen Sie im Allgemeinen
@class
zuerst eine Deklaration ausstellenquelle
Laut Matts Antwort hat die
@class
Erklärung in Ihrem Code absolut keinen Sinn .@class
forward definiert eine Klasse, damit der Compiler anschließend weiß, auf welche allgemeine Art von Einheit Sie sich beziehen. Da Objective-C zur Laufzeit so gut wie typenlos ist, ist dies oft alles, was der Compiler tatsächlich wissen muss - gerade genug, um das Ding von einem atomaren C-Wert zu unterscheiden.Ich werde einen Stich in die Dunkelheit machen und sagen, dass, weil die Instanzvariablen in der deklariert sind,
@interface
Sie einen alten Code betrachten. Da es sich um alten Code handelt, befand sich der Code@class
wahrscheinlich früher an einem anderen Ort (z. B. wurde dazwischen ein Delegatenprotokoll deklariert) und ist gerade harmlos gestrandet.quelle
@class ist sehr praktisch, wenn Sie ein Protokoll für ein Objekt definieren müssen, das normalerweise mit dem Objekt interagiert, dessen Schnittstelle Sie ebenfalls definieren. Mit @class können Sie die Protokolldefinition im Header Ihrer Klasse behalten. Dieses Delegierungsmuster wird häufig in Objective-C verwendet und ist häufig der Definition von "MyClass.h" und "MyClassDelegate.h" vorzuziehen. Dies kann zu verwirrenden Importproblemen führen
@class MyClass; @protocol MyClassDelegate<NSObject> - (void)myClassDidSomething:(MyClass *)myClass - (void)myClass:(MyClass *)myClass didSomethingWithResponse:(NSObject *)reponse - (BOOL)shouldMyClassDoSomething:(MyClass *)myClass; - (BOOL)shouldMyClass:(MyClass *)myClass doSomethingWithInput:(NSObject *)input @end // MyClass hasn't been defined yet, but MyClassDelegate will still compile even tho // params mention MyClass, because of the @class declaration. // You're telling the compiler "it's coming. don't worry". // You can't send MyClass any messages (you can't send messages in a protocol declaration anyway), // but it's important to note that @class only lets you reference the yet-to-be-defined class. That's all. // The compiler doesn't know anything about MyClass other than its definition is coming eventually. @interface MyClass : NSObject @property (nonatomic, assign) id<MyClassDelegate> delegate; - (void)doSomething; - (void)doSomethingWithInput:(NSObject *)input @end
Wenn Sie dann die Klasse verwenden, können Sie sowohl Instanzen der Klasse erstellen als auch das Protokoll mit einer einzigen Importanweisung implementieren
#import "MyClass.h" @interface MyOtherClass()<MyClassDelegate> @property (nonatomic, strong) MyClass *myClass; @end @implementation MyOtherClass #pragma mark - MyClassDelegate Protocol Methods - (void)myClassDidSomething:(MyClass *)myClass { NSLog(@"My Class Did Something!") } - (void)myClassDidSomethingWithResponse:(NSObject *)response { NSLog(@"My Class Did Something With %@", response); } - (BOOL)shouldMyClassDoSomething { return YES; - (BOOL)shouldMyClassDoSomethingWithInput:(NSObject *)input { if ([input isEqual:@YES]) { return YES; } return NO; } - (void)doSomething { self.myClass = [[MyClass alloc] init]; self.myClass.delegate = self; [self.myClass doSomething]; [self.myClass doSomethingWithInput:@0]; }
quelle