2012-04-04 19 views
67

这两个类声明有什么区别?我不明白为什么在这里使用@class。谢谢。Objective-C:@interface之前的@class指令?

@class TestClass; 

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

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

回答

165

@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,因为没有额外的元数据可供编译器使用(我不记得它是否将呼叫站点恢复为通过呼叫评估或者不是)。

在你的例子中,@class是无害的,但完全没有必要。

+17

我希望我可以给另一个+1只为'鸡,满足蛋' – lukya 2013-07-05 13:25:44

+4

顺便说一句,它确实恢复到'id'评估。 – jheld 2014-05-21 16:19:05

+0

为什么某些人在他们的.h文件中放入'@ class',然后在.m文件中导入必要的头文件,以及其他人可能只是将当前类头文件中的.h文件导入?只是好奇,谢谢。 @bbum – 2014-05-30 20:01:01

15
@class TestClass; 

这只是宣称 “类的TestClass将被定义为”。

在这种情况下(你粘贴的那个)这个没有任何影响,所以这些都是一样的。

但是,如果您要定义一个使用您的类名的协议(例如传递给委托的参数类型),您需要在协议定义之前声明@class TestClass,因为您的类是仍未定义。

一般来说,如果你需要的是由类定义之前提到你的类名,你将需要发出@class声明第一

+0

我见过落实协议这个实现是最大的 - 在协议之前。感谢分享! – SleepsOnNewspapers 2015-02-10 22:29:20

6

按照马特的答案绝对没有点在代码中@class声明。 @class forward定义了一个类,以便编译器随后知道您指的是什么类型的单位。由于Objective-C在运行时几乎是无类型的,通常编译器实际需要知道的仅仅是将它与原子C值区分开来。

我要在黑暗中进行刺探,并说因为实例变量在@interface中声明,所以您正在查看一些旧代码。因为它是旧代码,@class可能曾经是别的地方(例如,有一个委托协议声明),并最终被无害地搁浅。

1

当你需要为一个对象定义一个协议时,@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 

@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]; 

} 
相关问题