オブジェクトを UIViewController のサブクラスにすると、NSObject のサブクラスよりもかなり多くのメモリを使用しますか? 複雑なクラスと単純なクラスをサブクラス化することによって、どれだけ多くのオーバーヘッドが使用されるかについての概算値は素晴らしいでしょう。編集:または自分で違いを理解する方法。
5 に答える
これは、スーパークラスのインスタンス変数の数と性質によって異なります。NSObject
1 つの ivar、isa
ポインターがあります。UIViewController
には約 30 個の ivar があり、そのほとんどがポインターです (リストは で参照できますUIViewController.h
)。
したがって、 のサブクラスはUIViewController
、すべての ivar とそのスーパークラス ( UIResponder
(ivar なし) およびNSObject
(1 つの ivar)) のすべての ivar を格納するために必要なだけのメモリを占有します。
もちろん、この計算では、これらのインスタンス変数が初期化時に参照するオブジェクトによって使用される実際のメモリは考慮されていません。たとえば、完全に初期化されたビュー コントローラは、かなりの量のメモリを占有するビュー オブジェクトを保持する場合があります。
試してみてくださいclass_getInstanceSize([MyClass class]);
。大まかに言うと、インスタンスのメモリ使用量は、この値を 16 バイトの倍数に切り上げたものになります。もちろん、これには関連オブジェクトのオーバーヘッド (「 」を参照objc_setAssociatedObject
) やクラスによる割り当ては含まれません。
Objective-C オブジェクトは、次のような単なる C 構造体であると想像できます。
typedef struct {
Class isa;
} NSObject;
その構造体のインスタンスは、32 ビット システムで 4 バイトを使用します。単一のポインターで構成されているため、クラスは id に似ています。
1 つの 'char' インスタンス変数を持つ NSObject のサブクラス、MySubclass は次のようになります。
typedef struct {
Class isa;
char singleInstanceVariable.
} MySubclass;
サブクラスは、最初にそのスーパー クラスのすべてのインスタンス変数を持ち、最後に独自のインスタンス変数を持ちます。コンソールで「p *object」と入力すると、デバッガーでこれを確認できます。
MySubclass のサイズは、32 ビット システムでは 5 バイトになります。1 つのポインターと 1 つの文字。したがって、オブジェクトのサイズは、すべてのインスタンス変数を合計したサイズです。知っておくべき重要なことの 1 つは、オブジェクトのサイズはそのインスタンス変数にのみ関連するということです。メソッドの数の影響を受けません。これらのメソッドは、より多くのインスタンスがインスタンス化されるため、追加のメモリを消費しません。メソッドには固定の初期費用があります。
考慮すべきもう 1 つのことは、オブジェクトは通常、インスタンス変数として他のオブジェクトへのポインターを持っているということです。たとえば、すべての UIView に、そのサブビューを参照するための NSMutableArray があるとします。空の場合、その配列は 12 バイトになる可能性があります。したがって、空の UIView は UIView 内のすべての変数のサイズになり、配列へのポインターに 4 バイトが含まれます。さらに、実際の配列インスタンスによって使用される 12 の追加バイトを考慮することもできます。配列とビューは 2 つの別個のオブジェクトですが、ビューは配列なしでは実際には使用できません。
最後に、ほとんどの割り当ては、malloc の実装を高速化し、マシンのアーキテクチャのいくつかの制約を満たすために、ポインターが適切に整列されるように、いくつかのクォンタムに切り上げられます。また、オブジェクトのインスタンス変数には、構造体のパディングと同様に、それらの間に空のパディングがある場合があります
要するに、そうですが、数万個のインスタンスを作成する予定がない限り、心配する必要があるほどではないでしょう。
オブジェクトは、ivar とそのメソッドのそれぞれにメモリを割り当てます。必要なメモリの量は C の型によって異なります...それらはすべて、格納されているデータ型によって異なります。
使用されるメモリの量は、オブジェクトがどのようにインスタンス化され、画面に表示され、操作されるかによって異なります。たとえば、NSObject のサブクラスは、ユーザーのタッチと相互作用しません。
違いを比較するために、Instruments Allocations パフォーマンス ツールを使用していつでもアプリケーションを添付できます。