Objective-C: Directive @class avant @interface?

Quelle est la différence entre ces deux déclarations de classe? Je ne comprends pas pourquoi @class est utilisé ici. Merci.

@class TestClass; @interface TestClass: UIView { UIImage *image1; UIImage *image2; } 

et

 @interface TestClass: UIView { UIImage *image1; UIImage *image2; } 

@class existe pour briser les dépendances circulaires. Disons que vous avez des classes A et B.

 @interface A:NSObject - (B*)calculateMyBNess; @end @interface B:NSObject - (A*)calculateMyANess; @end 

Poulet; rencontrer Egg. Cela ne peut jamais se comstackr car l’interface de A dépend de la définition de B et vice-versa.

Ainsi, il peut être corrigé en utilisant @class :

 @class B; @interface A:NSObject - (B*)calculateMyBNess; @end @interface B:NSObject - (A*)calculateMyANess; @end 

@class indique effectivement au compilateur qu’une telle classe existe quelque part et que, par conséquent, les pointeurs déclarés pour pointer vers des instances de cette classe sont parfaitement valides. Cependant, vous ne pouvez pas appeler une méthode sur une référence d’instance dont le type est uniquement défini en tant que @class car il n’y a pas de métadonnées supplémentaires disponibles pour le compilateur (je ne me souviens pas si le site d’appel est évalué en tant qu’appel) via id ou non).

Dans votre exemple, @class est inoffensif, mais totalement inutile.

 @class TestClass; 

Cela déclare simplement “la classe TestClass sera définie”.

Dans ce cas (celui que vous avez collé) cela n’a aucun effet, donc ce sont les mêmes.

Cependant, au cas où vous définiriez un protocole qui utiliserait votre nom de classe (comme type de parameters transmis à un délégué, par exemple), vous devrez déclarer @class TestClass avant la définition du protocole, votre classe n’étant toujours pas défini.

En général, si vous devez mentionner le nom de votre classe avant que la définition de la classe ne soit faite, vous devez d’abord envoyer la déclaration @class

Selon la réponse de Matt, la déclaration @class n’est absolument pas @class dans votre code. @class forward définit une classe afin que le compilateur sache par la suite à quel type d’unité vous faites référence. Puisque Objective-C est quasiment sans typage à l’exécution, c’est souvent tout ce que le compilateur a besoin de savoir – juste assez pour distinguer la chose d’une valeur C atomique.

Je vais prendre un coup dans l’obscurité et dire que parce que les variables d’instance sont déclarées dans l’ @interface vous regardez un ancien code. Parce que c’est de l’ancien code, la @class probablement ailleurs (par exemple, il y avait un protocole de délégué déclaré entre les deux) et vient tout juste de se terminer sans problème.

@class est très pratique lorsque vous devez définir un protocole pour un object qui interagira généralement avec l’object dont vous définissez également l’interface. En utilisant @class, vous pouvez conserver la définition du protocole dans l’en-tête de votre classe. Ce modèle de délégation est souvent utilisé sur Objective-C et est souvent préférable à la définition à la fois de “MyClass.h” et de “MyClassDelegate.h”. Cela peut causer des problèmes d’importation déroutants

 @class MyClass; @protocol MyClassDelegate - (void)myClassDidSomething:(MyClass *)myClass - (void)myClass:(MyClass *)myClass didSomethingWithResponse:(NSObject *)reponse - (BOOL)shouldMyClassDoSomething:(MyClass *)myClass; - (BOOL)shouldMyClass:(MyClass *)myClass doSomethingWithInput:(NSObject *)input @end @interface MyClass : NSObject @property (nonatomic, assign) id delegate; - (void)doSomething; - (void)doSomethingWithInput:(NSObject *)input @end 

Ensuite, lorsque vous utilisez la classe, vous pouvez créer des instances de la classe et implémenter le protocole avec une seule instruction d’importation.

 #import "MyClass.h" @interface MyOtherClass() @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]; }