0

I'm playing around with some code in a Kobold2D example project (Orthogonal Tile based Game) and I've noticed:

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

in the TileMapLayer.h file, and:

@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

in the TileMapLay.m file.

I've always thought that .h files hold interfaces and .m files store implementations

Can someone please explain their purpose (started from the basics, I'm still learning Objective C) and what the difference in purpose between the 2 examples above?

  • And of course you mean the `.m` file, not the `.c` file. And your question doesn't actually seem to be about the `@implementation`, just `@interface`. – rmaddy Jul 18 '13 at 23:15
  • Lol yeah i meant `.m`, you can tell i started out with `.c` –  Jul 18 '13 at 23:24

3 Answers3

2

What you put in a header and implementation file is entirely up to you. They all get concatenated by the preprocessor before compilation anyway. It's convention to put external interfaces that other compilation units might want to use into header files. The person who wrote your example code intends to keep all of those properties defined in the .m file private - that is they're intended to not be directly accessed by other code in the system.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
  • 1
    that is correct i guess in regard to a class in particular... but visibility to other classes and legacy runtime support are 2 real issues that make it not "entirely up to you" – Grady Player Jul 18 '13 at 23:22
1

First notice that .m are Objective-C files (which can have both Objective-C and C) and .c are plain C files which can only contain C code. Both employ the .h extension for the header.

Regarding Objective-C, the .m file does @interface TileMapLayer() to declare a class extension. A class extension can add ivars and properties to a Class that was already declared in the .h file. An extension is only viewable from within its own .m file. It doesn't make much sense to declare an extension inside an .h file, but I guess you could if you wanted.

Regarding purpose, a recommended practice is declaring the minimum amount of properties needed in the .h in order to keep the interface lean and clean. For properties that are only needed inside the class, you can declare them in the extension on the .m file. My personal preference is to avoid explicitly declaring and using ivars at all (unless I'm overriding a property setter or getter), because that way on the implementation I can tell at first glance which variables are local to the function or object properties. The overhead is usually negligible and I prefer to code for readability than to prematurely optimize. With the recently introduced auto-synthesized properties this saves a lot of boilerplate code as well.

A strategy that I also recommend is thinking carefully which properties should be modifiable from outside the object or not. Declare the non-modifiable properties as readonly in the .h files. Then, you can re-declare them as readwrite in the .m extension for operations from the object itself. This ensures that you or your colleagues don't commit the mistake and modify a readonly property that is not supposed to change from outside the object. In a sense it helps you in keeping the logic of the object inside it. I would try to avoid the trap of declaring everything readwrite (the default), because then it usually comes to bite you back later.

Ricardo Sanchez-Saez
  • 9,466
  • 8
  • 53
  • 92
  • 1
    The `.c` thing was just a freudian slip :p "Then, you can re-declare them as readwrite in the .m extension for operations from the object itself." +1 –  Jul 19 '13 at 00:16
0

Things defined in .h can be used by any .m files as long as the .m includes the .h. But things defined in .m can only be used in current .m file.

Macmade
  • 52,708
  • 13
  • 106
  • 123
TieDad
  • 9,143
  • 5
  • 32
  • 58