标题#import与@class [英] Headers #import versus @class
问题描述
可能重复:
@class vs. #import
在.h文件中,您可以添加通过使用
In the .h file you can add a class to be seen(dont know what the correct terminolgy for this is) by using
#import "SomeClass.h"
或改为使用
@class SomeClass;
我尝试了两种方法,但它们都有效。有什么不同?我应该使用其中一种方法而不是其他方法吗?什么是最佳做法?
I've tried both methods and they both worked. Whats the difference? Should I be using one of the methods and not the other? What is best practice?
推荐答案
#import
包含的内容源头中的标题。
因此,导入标题中的每个声明也会被导入。
#import
includes the content of the header in the source.
Thus, every declaration which is in the imported header is also imported.
@class
仅声明到编译器,给定的类存在,但不导入标头本身。它被称为前向声明,因为您只向编译器声明该类存在之前详细定义它(告诉它实现了哪些方法等等)
@class
only declares to the compiler that the given class exists, but does not import the header itself. It is called a forward declaration, as you only declares to the compiler that the class exists before defining it in details (telling which methods it implements and so on)
后果:
- 使用
#import $ c时$ c>在你的
.m
文件中,如果标题被修改,它将触发重新编译.m
在下次编译时将文件#import
下载。相反,如果你使用@class
,你的.m
不依赖于标题,如果标题被修改,.m
文件未重新编译。 - 使用
@class
也避免交叉进口,例如如果A类引用B类而B类引用A类,则Bh 和 <$ c中不能#importAh
$ c> #import Bh 同时在Ah中(这将是一个导入无限循环) - 使用
@class
只声明一个类存在,并且不告诉编译器该类响应的方法。
- When using
#import
in your.m
file, if the header is modified, it will trigger the recompilation of the.m
file that#import
it on next compilation. Instead, if you use@class
, your.m
does not depend on the header and if the header is modified, the.m
file is not recompiled. - Using
@class
also avoid cross-imports, e.g. if the class A references class B and class B references class A, then you can't#import "A.h"
in B.h and#import B.h
in A.h in the same time (it would be an "import infinite loop") - Using
@class
only declare that a class exists and does not tell the compiler which methods the class responds to.
这个为什么通常最佳做法是在引用A类的标题(.h)文件中使用 @class A
转发声明该类,只是为了让编译器知道A是一个已知的类,但不需要知道更多,和 #import啊
在实现中(。 m)文件,以便您可以在源文件中调用A类对象上的方法。
This is why usually the best practice is to forward-declare the class using @class A
in the header (.h) files that references class A, just so that the compiler knows that "A" is a known class but doesn't need to know more, and #import "A.h"
in the implementation (.m) file so that you can call methods on the objet of class A in your source file.
除了避免导入循环,这个如果不需要,也会避免重新编译文件,从而减少编译时间。
唯一的删除eptions是当你的类的声明继承另一个类,或者它声明它符合给定的 @protocol
(如委托协议等)时,因为在这个特定的例如,编译器需要你 #import
父类的整个定义或 @protocol
(要知道你的class正确符合这个给定的协议)。
The only exceptions are when the declaration of your class inherits another class, or when it declares that it conforms to a given @protocol
(like delegate protocols and so on), because in this particular case, the compiler needs you to #import
the whole definition of the parent class or @protocol
(to know if your class correctly conforms to this given protocol).
MyClassA.h
MyClassA.h
// Tells the compiler that "MyClassB" is a class, that we will define later
@class MyClassB; // no need to #import the whole class, we don't need to know the whole definition at this stage
@interface MyClassA : NSObject {
MyClassB* someB; // ok, the compiler knows that MyClassB is a class, that's all it needs to know so far
}
-(void)sayHello;
-(void)makeBTalk;
@end
MyClassB.h
MyClassB.h
@class MyClassA; // forward declaration here too
// anyway we couldn't #import "MyClassA.h" here AND #import "MyClassB.h" in MyClassA.h as it would create an unsolvable import loop for the compiler
@interface MyClassB : NSObject {
MyClassA* someA; // ok, the compiler knows that MyClassA is a class, that's all it needs to know so far
}
-(void)talk;
-(void)makeABePolite;
@end
MyClassA.m
MyClassA.m
// import MyClassB so that we know the whole definition of MyClassB, including the methods it declares
#import "MyClassB.h" // thus we here know the "-talk" method of MyClassB and we are able to call it
@implementation MyClassA
-(void)sayHello { NSLog(@"A says Hello"); }
-(void)makeBTalk {
[someB talk];
// we can call the 'talk' method because we #imported the MyClassB header and knows this method exists
}
@end
MyClassB.m
MyClassB.m
// import MyClassA so that we know the methods it declares and can call them
#import "MyClassA.h"
@implementation MyClassB
-(void)talk { NSLog(@"B is talking"); }
-(void)makeABePolite {
[someA sayHello];
// we can call this because we #import MyClassA
}
@end
PS:请注意,如果这是最佳做法,我知道很多开发人员(包括我自己有时^^) #import
标题它需要在他们的.h文件中,而不是仅使用 @class
向前声明...这是一个坏习惯 - 或者因为这些开发人员不知道这些微妙之处 - 无论如何,您将不幸遇到现有代码。
PS: Note that if this is a best practice, I know a lot of developers (including myself sometimes ^^) that #import
the header it needs in their .h files, instead of only forward-declare it using @class
... this is some bad habit — or because these developers doesn't know these subtleties — that you will unfortunately encounter in existing code anyway.
这篇关于标题#import与@class的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!