ヘッダーファイルにおいて、#define(マクロ)を使って、(公開/非公開に関わらず)全ての定数にプレフィックスkをつけて定義しているコードを見かけることがあるが、下記理由から個人的にはあまり良くないのではないかと思っている。
- 型情報がない
- ヘッダーファイルインポート条件によっては、名前衝突により開発者が意図しないファイルにおいても定数置換が行われてしまう危険性がある
実際のところ、私は下記のように定数定義を行っている。
外部に公開する定数
- extern constを付与
- 定数にはプレフィックスとしてクラス名をつける(名前衝突を避けるため)
内部でのみ使用する定数
- static constを付与
- 定数にはプレフィックスとしてkをつける(よく見かけるパターン)
コーディング例
以下は、BLGClassAクラスにおいて外部に公開する定数を定義、BLGClassBクラスにおいて内部で使用する定数を定義、して利用する場合の例。
BLGClassA.h
#import <Foundation/Foundation.h>
@interface BLGClassA : NSObject
extern const NSInteger BLGClassAIntegerConstant;
extern NSString *const BLGClassAStringConstant;
@end
BLGClassA.m
#import “BLGClassA.h"
const NSInteger BLGClassAIntegerConstant = 3;
NSString *const BLGClassAStringConstant = @"hogePublic";
@implementation BLGClassA
// NSObjectクラスにはinitメソッドが実装されているため、省略可能
//- (id)init {
// if (self = [super init]) {
// }
// return self;
//}
@end
BLGClassB.h
#import <Foundation/Foundation.h>
@interface BLGClassB : NSObject
- (void)doSomething;
@end
BLGClassB.m
#import “BLGClassB.h"
#import “BLGClassA.h"
static const NSInteger kLocalIntegerConstant = 30;
static NSString *const kLocalStringConstant = @"fooLocal";
@implementation BLGClassB
// NSObjectクラスにはinitメソッドが実装されているため、省略可能
//- (id)init {
// if (self = [super init]) {
// }
// return self;
//}
- (void)doSomething
{
NSLog(@"Local Constants: %ld %@", (long)kLocalIntegerConstant, kLocalStringConstant);
NSLog(@"Imported Constants: %ld %@", (long)BLGClassAIntegerConstant, BLGClassAStringConstant);
}
@end
main.m
#import <Foundation/Foundation.h>
#import “BLGClassB.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
BLGClassB *b = [BLGClassB new];
[b doSomething];
// Local Constants: 30 fooLocal
// Imported Constants: 3 hogePublic
}
return 0;
}