这两个类声明有什么区别?我不明白为什么在这里使用@class。谢谢。
@class TestClass;
@interface TestClass: UIView {
UIImage *image1;
UIImage *image2;
}
和
@interface TestClass: UIView {
UIImage *image1;
UIImage *image2;
}
这两个类声明有什么区别?我不明白为什么在这里使用@class。谢谢。
@class TestClass;
@interface TestClass: UIView {
UIImage *image1;
UIImage *image2;
}
和
@interface TestClass: UIView {
UIImage *image1;
UIImage *image2;
}
@class
存在打破循环依赖。假设你有 A 类和 B 类。
@interface A:NSObject
- (B*)calculateMyBNess;
@end
@interface B:NSObject
- (A*)calculateMyANess;
@end
鸡; 遇见蛋。这永远无法编译,因为 A 的接口取决于 B 的定义,反之亦然。
因此,它可以通过使用来修复@class
:
@class B;
@interface A:NSObject
- (B*)calculateMyBNess;
@end
@interface B:NSObject
- (A*)calculateMyANess;
@end
@class
有效地告诉编译器这样的类存在于某处,因此,声明为指向所述类的实例的指针是完全有效的。但是,您无法在类型仅定义为的实例引用上调用方法,@class
因为编译器没有可用的其他元数据(我不记得它是否将调用站点恢复为通过调用id
或不是)。
在您的示例中,这@class
是无害的,但完全没有必要。
@class TestClass;
这只是声明“将定义类 TestClass”。
在这种情况下(您粘贴的那个),这没有任何效果,所以它们是相同的。
但是,如果您要定义一个使用您的类名的协议(例如,作为传递给委托的参数类型),您需要@class TestClass
在协议定义之前声明,因为您的类仍未定义。
一般来说,如果你需要在类定义之前提到你的类名,你需要先发出@class
声明
根据马特的回答@class
,您的代码中的声明绝对没有意义。@class
forward 定义了一个类,以便编译器随后知道您所指的一般类型的单元。由于 Objective-C 在运行时几乎是无类型的,这通常是编译器实际需要知道的全部内容 - 足以将事物与原子 C 值区分开来。
我将在黑暗中刺痛并说因为实例变量是在@interface
您正在查看一些旧代码中声明的。因为它是旧代码,它@class
可能曾经在其他地方(例如,在两者之间声明了一个委托协议)并且刚刚结束了无害的搁浅。
当您需要为一个对象定义一个协议时,@class 非常方便,该协议通常会与您也定义其接口的对象交互。使用@class,您可以将协议定义保留在类的标题中。这种委托模式经常用在 Objective-C 上,通常比定义“MyClass.h”和“MyClassDelegate.h”更可取。这可能会导致一些令人困惑的导入问题
@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
然后,当您使用该类时,您既可以创建该类的实例,也可以使用单个 import 语句实现协议
#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];
}