关于C#:@interface或@implementation在.h或.c之间的区别是什么

What's the difference between @interface or @implementation being in .h or .c

本问题已经有最佳答案,请猛点这里访问。

我正在一个Kobold2d示例项目(基于正交图块的游戏)中玩一些代码,我注意到:

1
2
3
4
5
@interface TileMapLayer : CCLayer //Map
{
    float tileMapHeightInPixels; //depricated@interface TileMapLayer()  
}
@end

在tilemaplayer.h文件中,以及:

1
2
3
4
5
6
7
8
9
10
11
@interface TileMapLayer()
@property (strong) HUDLayer *hud;
@property (strong) CCTMXTiledMap *tileMap;
@property (strong) CCTMXLayer *background;
@property (strong) CCTMXLayer *foreground;
@property (strong) CCTMXLayer *meta;
@property (strong) CCTMXLayer *base;
@property (strong) CCSprite *player;
@property (strong) CCSprite *playerTurret;
@property (assign) int money;
@end

在tilemaplay.m文件中。

我一直认为.h文件包含接口和.m文件存储实现。

有人能解释一下他们的目的(从基础开始,我还在学习目标C)和上面两个例子的目的有什么区别吗?


在头文件和实现文件中放置的内容完全由您决定。无论如何,在编译之前,它们都会被预处理器连接起来。将其他编译单元可能希望使用的外部接口放入头文件是惯例。编写示例代码的人打算将.m文件中定义的所有属性保持为私有,即它们不被系统中的其他代码直接访问。


首先要注意的是,.m是objective-c文件(可以同时具有objective-c和c),.c是纯c文件,只能包含c代码。两者都使用.h扩展头段。

对于objective-c,.m文件执行@interface TileMapLayer()来声明类扩展。类扩展可以向已经在.h文件中声明的类添加ivar和属性。扩展名只能从它自己的.m文件中查看。在.h文件中声明扩展名没有多大意义,但如果需要的话,我想您可以这样做。

就目的而言,建议的做法是声明.h中所需的最小属性数量,以保持界面的清洁和清洁。对于类内只需要的属性,可以在.m文件的扩展名中声明它们。我的个人偏好是完全避免显式声明和使用ivar(除非我重写属性设置器或getter),因为在实现过程中,我可以一眼就知道哪些变量是函数或对象属性的局部变量。开销通常可以忽略不计,我更喜欢代码的可读性,而不是过早地优化。随着最近引入的自动合成属性,这也节省了大量样板代码。

我还建议您仔细考虑哪些属性应该从对象外部进行修改。在.h文件中将不可修改的属性声明为readonly。然后,在对象本身的操作的.m扩展中,您可以将它们重新声明为readwrite。这样可以确保您或您的同事不会犯错误,并修改不应该从对象外部更改的readonly属性。在某种意义上,它可以帮助您保持对象的逻辑在其中。我会尽量避免声明所有东西的陷阱readwrite(默认值),因为之后它通常会咬你一口。


.h中定义的内容可以被任何.m文件使用,只要.m包含.h.。但是.m中定义的内容只能在当前.m文件中使用。