0

我正在玩 Kobold2D 示例项目(基于正交平铺的游戏)中的一些代码,我注意到:

@interface TileMapLayer : CCLayer //Map
{
    float tileMapHeightInPixels; //depricated@interface TileMapLayer()  
}
@end

在 TileMapLayer.h 文件中,并且:

@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)以及上面两个例子的目的有什么区别?

4

3 回答 3

2

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

于 2013-07-18T23:13:45.880 回答
1

首先要注意的.m是 Objective-C 文件(可以同时包含 Objective-C 和 C)并且.c是纯 C 文件,只能包含 C 代码。两者都使用.h标题的扩展名。

关于 Objective-C,该.m文件确实@interface TileMapLayer()声明了一个类扩展。类扩展可以将 ivars 和属性添加到已在.h文件中声明的类。扩展只能从其自己的.m文件中查看。在文件中声明扩展名没有多大意义.h,但我想如果你愿意的话。

关于目的,推荐的做法是声明所需的最少属性数量,.h以保持界面简洁和干净。对于仅在类内部需要的属性,您可以在.m文件的扩展名中声明它们。我个人的偏好是完全避免显式声明和使用 ivars(除非我重写了属性设置器或获取器),因为这样在实现上我可以一眼看出哪些变量是函数或对象属性的本地变量。开销通常可以忽略不计,我更喜欢编写可读性代码而不是过早优化。借助最近引入的自动合成属性,这也节省了大量样板代码。

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

于 2013-07-18T23:54:43.710 回答
0

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

于 2013-07-18T23:14:19.353 回答