2011年11月1日火曜日

Objective-cにおける文字列定数について

Objective-cで文字列定数を作成する場合どうしてますか? 多分、簡単に考えるとプリプロセッサを使って以下のように
Objective-cでの文字列定数(普通に考えると)
#define CONST_STRING    @"const string."
でも、C/C++言語的には定数のプリプロセッサ使用は好まれません、2重定義がうざいですからね。 なんというか、誰からも参照可能な反面まったく使用しないクラスにおいても同名で定義する事が 出来なくなります。
C++での文字列定数
因みに、C++の場合は以下のように定義しています。(Effective c++の受け売りですが)
const char * const CONST_STRING = "const string.";
要するに、実体もポインタも変更不可な変数です。
Javaでの文字列定数
Javaで書くとこうなるのかな。
private static final String CONST_STRING = "const string.";
Objective-cでの文字列定数(私はこうする)
でもって、Objective-cでは文字列定数をどう定義するべきか。なのです。 因みにプリプロセッサの使用は推奨されていないみたいですね。
[ Naming Instance Variables and Data Types ]

C言語なので、この場合はconstを使います。が、NSStringクラス自体がImmutableなクラスですので、以下のように。
@implementation SampleClass

static NSString * const CONST_STRING = @"const string";

- (id) init {
}

+ (NSString*) constString {
        return CONST_STRING;
}
@end
因みにこのstaticはこのファイル(クラス)に閉じるという意味です。ゲッタを作成してこの定数を返すようにすればJavaっぽく使えると 思います。 もちろん、文字列定数の場合です。当然かも知れませんが、数値の場合はenumの使用が推奨されているみたいですね。

[2013/12/01 追記]
Effective Objective-C2.0を読みました。文字列定数について言及されていましたので、 私の考えと異なっていた部分について追記します。定数の定義は前述したとおりの定義で認識合っていましたが、 他のクラス(ファイル)との共有方法が異なっていました。 Effective Objective-C2.0では以下のようにヘッダファイルに定義を追加します。上記の例だと、
extern NSString * const CONST_STRING;
と定義を追加します。そして、定数を使用したいクラスで本ヘッダファイルを引き込む事で直接利用可能にします。また、上記例で実装部では staticを付与していましたが、他のファイルでも参照可能にするため、static定義を削除して以下のように定義します。
NSString *const CONST_STRING = @"const string";
Objective-C自体がC言語仕様を継承しているので、このように記述できますが、グローバル変数として定義することになるため、 変数の命名方法に注意する必要があります。 Objective-Cでは組み込みの名前空間機能を持っていないので、同名の変数が定義されて名前の衝突が起きることが懸念されます。 名前の衝突はリンクエラーになるため、エラーになったら名前を変更すれば良いという楽観的な考えで定義してしまうと、 ライブラリのように他のモジュールから利用される事を前提としている場合は厄介なことになります。 グローバル変数を定義する場合は、特定のプレフィックスを付けて定義するすることで回避できると思いますので、 自分のプログラムとしてプレフィックスを考えて定義する必要があるでしょう。 ここでは記載しませんが、Effective Objective-C2.0では名前空間として衝突をさけるためにプレフィックス名を使用 することを推奨しており、一般的な命名則についての言及がありました。興味ある方は、以下リンクからどうぞ。
Effective Objective-C 2.0
Effective Objective-C 2.0
posted with amazlet at 13.11.12
Matt Galloway
翔泳社
売り上げランキング: 1,964

0 件のコメント :

コメントを投稿