オブジェクト生成時の*とは

Objective-C や C でオブジェクト生成時に"*"を付けます。普段当たり前のように利用しているため何の疑問もなく付けていますが、このケースに限らず自分の中で当たり前に習慣化していることについて質問や説明を求められたとき、「あれっ、そういえば」と思うことってあったりしたことがあるかと思います。今回は Objective-C では当たり前のように付ける"*"についてまとめてみました。

Objective-C では変数宣言するとき以下のように行います。

NSString *tuna = @"tunanosuke blog"

NSString *型の tuna という変数を宣言しています。これはポインタとよばれ、"*"を付けることで tuna という変数は文字列そのものを格納しているのではなく、文字列が格納されているポインタ(住所)を格納しています。Objective-C オブジェクトのためのメモリはヒープ空間から確保されます。スタック上に作られることはないです。そのため、"*"を付けて宣言する必要があります。以下の宣言はもちろんですが、エラーになります。

NSString tuna = @"tunanosuke blog"

図にするとこんな感じ。

f:id:tunanosuke:20140501172903p:plain

スタック領域はプリミティブ型データ、ポインタを確保。ヒープ領域はクラスの実態を保持します。またスタック領域はそのまま領域が使えるのでアクセスが高速です。ヒープ領域は図のようにポインタから実態を見るので若干ですが速度が落ちます。

スタック領域は自動的にクリーンアップされます。それに対しヒープ領域に確保されたメモリは直接管理する必要があります。ただ、Objective-C では ARC 機能がありますので、ある程度抽象化はされています。

基本的なことではありますが、"*"についての内部的な部分についてまとめてみました。