@class
existe para romper las dependencias circulares. Digamos que tienes clases A y B.
@interface A:NSObject
- (B*)calculateMyBNess;
@end
@interface B:NSObject
- (A*)calculateMyANess;
@end
Pollo; conoce a Egg. Esto nunca se puede compilar porque la interfaz de A depende de la definición de B y viceversa.
Por lo tanto, se puede solucionar usando @class
:
@class B;
@interface A:NSObject
- (B*)calculateMyBNess;
@end
@interface B:NSObject
- (A*)calculateMyANess;
@end
@class
le dice efectivamente al compilador que tal clase existe en algún lugar y, por lo tanto, los punteros declarados para apuntar a instancias de dicha clase son perfectamente válidos. Sin embargo, no podría llamar a un método en una referencia de instancia cuyo tipo solo se define como un @class
porque no hay metadatos adicionales disponibles para el compilador (no recuerdo si revierte el sitio de la llamada para que se evalúe como una llamada a través de id
o no).
En su ejemplo, el @class
es inofensivo, pero completamente innecesario.
id
evaluación.@class
ingresan su archivo .h y luego importan los archivos de encabezado necesarios en su archivo .m, y otros pueden simplemente importar el archivo .h en el archivo de encabezado de clases actual? Solo curiosidad, gracias. @bbum@class TestClass;
Esto simplemente declara "la clase TestClass será definida".
En este caso (el que pegaste), esto no tiene ningún efecto, por lo que son iguales.
Sin embargo, en caso de que vaya a definir un protocolo que use su nombre de clase (como tipo de parámetros pasados al delegado, por ejemplo), deberá declarar
@class TestClass
antes de la definición del protocolo, ya que su clase aún no está definida.En general, si necesita mencionar el nombre de su clase antes de realizar la definición de la clase,
@class
primero deberá emitir una declaraciónfuente
Según la respuesta de Matt, no tiene ningún sentido la
@class
declaración en su código.@class
forward define una clase para que el compilador sepa posteriormente a qué tipo general de unidad se refiere. Dado que Objective-C no tiene prácticamente ningún tipo en tiempo de ejecución, a menudo eso es todo lo que el compilador necesita saber, lo suficiente para distinguir la cosa de un valor C atómico.Voy a intentarlo en la oscuridad y diré que debido a que las variables de instancia están declaradas en el
@interface
, estás viendo un código antiguo. Debido a que es un código antiguo,@class
probablemente solía estar en otro lugar (por ejemplo, había un protocolo de delegado declarado en el medio) y acaba de terminar inofensivamente varado.fuente
@class es bastante útil cuando necesita definir un protocolo para un objeto que normalmente interactuará con el objeto cuya interfaz también está definiendo. Usando @class, puede mantener la definición del protocolo en el encabezado de su clase. Este patrón de delegación se usa a menudo en Objective-C y, a menudo, es preferible a definir tanto "MyClass.h" como "MyClassDelegate.h". Eso puede causar algunos problemas de importación confusos.
@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
Luego, cuando esté usando la clase, puede crear instancias de la clase e implementar el protocolo con una sola declaración de importación
#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]; }
fuente