BACK INDEX NEXT

Cocoaのメモリ管理(1)

Objective-Cを使用してCocoaプログラミングを行う上で、オブジェクトのメモリ管理は非常に重要な要素です。そこで最初のテーマとして、オブジェクトのメモリ管理を取り上げてみます。

さて、Cocoaにおけるオブジェクトのメモリ管理の枠組みは、その基盤をなすフレームワークであるFoundation Kitによって提供されています。ここに定義されるルートクラスNSObjectには、その枠組みを実現するための、いくつかのメソッドが用意されています。ここでは、それらのメソッドを紹介しながら、メモリ管理をいかにすべきかを学んでいきたいと思います。

オブジェクトの生成

オブジェクトの生成は、そのままそのオブジェクトのためにメモリを割り当てることです。Objective-Cには、JavaやC++のようにコンストラクタというものは存在せず、クラスメソッド(Javaでいうところのstaticメソッドに近い)とインスタンスメソッドという二種類のメソッドがあるだけです。コンストラクタなしでどうやってオブジェクトを生成するかというと、コンストラクタの働きをするクラスメソッドをクラスに対して呼び出すことで、実際のメモリ割り当てを行います。NSObjectには、以下のようなクラスメソッドが用意されています。二番目のメソッドの引数であるNSZoneというのは、あらかじめ確保された名前でも参照可能なメモリ空間をさし、複数のNSZoneを利用することが可能です。用途に応じてNSZoneを使い分けることで、効率的なアプリケーションを設計することが可能になるでしょう。しかしながら、通常はallocのほうを使うことが多いと思います。さて、これらのメソッドはサブクラスでオーバライドすることも、別な名前のクラスメソッドを用意して、それによってオブジェクトを生成させることもできます。しかし、それらは、特別なメモリ割り当て、たとえば、作業用バッファを同時に確保するなどの場合であり、通常の使用では、オーバライドする必要はないと考えて構わないでしょう。

+ (id)alloc
+ (id)allocWithZone:(NSZone *)zone

オブジェクトの初期化

さて、割り当てられたばかりのオブジェクトは、初期化がなされていません。初期化の主な役割はインスタンス変数の初期化を行い、オブジェクトを動作可能な状態に持っていくことです。そこで、初期化を行うための以下のインスタンスメソッドが用意されています。一般的に、そのクラス独自のインスタンス変数の初期化のために、このメソッドはオーバライドすることが多いでしょう。ただし、これもNSObjectでこのような名前で定義されているだけで、サブクラスでは別な名前の初期化メソッドを用意できます。というか、用意しなければならない局面が往々にして存在します。どういうことかというと、このインスタンス変数の初期化のために他の情報を必要とする場合があります。その場合は、引数つきの初期化メソッドを用意して、それを呼び出すようにするわけです。

- (id)init

実例

これらのメソッドを使用した例を以下に示します。これは、Fooクラスのオブジェクトを割り当て、変数objとして初期化した例です。

    id obj = [[Foo alloc] init];

ちなみに、以下のコードはまずいので、注意が必要です。なぜなら、initメソッドの戻り値が別なオブジェクトを返したり、nilを返すこともあるからです。

    id obj = [Foo alloc];
    [obj init];

◆この稿の執筆にあたり、以下の方に感謝いたします。ありがとうございます。
・牧野 義樹さん <m-yoshi@jaist.ac.jp>
BACK INDEX NEXT