我在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)以及上述两个例子之间的目的有何不同?
答案 0 :(得分:2)
您在标题和实现文件中放置的内容完全取决于您。无论如何,它们都会在编译之前被预处理器连接起来。通常将其他编译单元可能想要使用的外部接口放入头文件中。编写示例代码的人打算将.m
文件中定义的所有属性保密为私有 - 也就是说它们不会被系统中的其他代码直接访问。
答案 1 :(得分:1)
首先注意.m
是Objective-C文件(可以同时具有Objective-C和C)和.c
是纯C文件,只能包含C代码。两者都使用标题的.h
扩展名。
关于Objective-C,.m
文件执行@interface TileMapLayer()
来声明类扩展名。类扩展可以将ivars和属性添加到已在.h
文件中声明的类中。扩展只能在其自己的.m
文件中查看。在.h
文件中声明扩展名没有多大意义,但我想如果你愿意的话可以。
关于目的,建议的做法是声明.h
中所需的最小属性数量,以保持界面的精简和清洁。对于只在类中需要的属性,可以在.m
文件的扩展名中声明它们。我个人的偏好是避免明确地声明和使用ivars(除非我重写属性setter或getter),因为在实现上我可以乍一看哪些变量是函数或对象属性的本地变量。开销通常可以忽略不计,我更喜欢编写可读性而不是过早优化。通过最近引入的自动合成属性,这也节省了大量的样板代码。
我还建议的策略是仔细考虑哪些属性应该可以从对象外部修改。在readonly
文件中将不可修改的属性声明为.h
。然后,您可以在readwrite
扩展程序中将它们重新声明为.m
,以便从对象本身进行操作。这可以确保您或您的同事不会提交错误并修改不应从对象外部更改的readonly
属性。从某种意义上说,它可以帮助您保持对象内部的逻辑。我会尽量避免声明所有内容readwrite
(默认值)的陷阱,因为它通常会在以后咬你。
答案 2 :(得分:0)