web-dev-qa-db-ja.com

Objective-Cでオブジェクトのサイズを確認する

私はobjective-cオブジェクトのサイズを見つけようとしています。私は次のようなものを使用しています:

    NSLog(@"sizeof myObject: %ld", sizeof(*myObject));

それでもポインタのサイズがわかります。

何が悪いのですか?

35
Coocoo4Cocoa

コンパイラーが知っているのはポインターだけです。そのため、ポインターのサイズが返されます。割り当てられたオブジェクトのサイズを確認するには、次のコードスニペットのいずれかを使用します。

ARCの場合:

#import <malloc/malloc.h>

// ...

NSLog(@"Size of %@: %zd", NSStringFromClass([myObject class]), malloc_size((__bridge const void *) myObject));

ARCなし:

#import <malloc/malloc.h>

// ...

NSLog(@"size of myObject: %zd", malloc_size(myObject));

Mike Ashは、彼のQ&AブログでいくつかのObj-Cランタイム内部についてまともな記事を書いています: http://mikeash.com/?page=pyblog/friday-qa-2009-03-13-intro -to-the-objective-c-runtime.html

53
Jason Coco

GNU Objective-Cランタイムで使用できます(<objc/objc-api.h>をインポートする必要があります:

class_get_instance_size ([MyClass class]);

Mac OS Xでは使用できます(<objc/runtime.h>のインポートが必要になる場合があります):

class_getInstanceSize ([MyClass class]);

これらの関数は、オブジェクトの割り当てに必要なメモリ量を返します。初期化時にオブジェクトによって割り当てられたメモリは含まれません。

19
dreamlax

まず第一に、私は上記の投稿から、objectサイズがmalloc_size(myObject)によって与えられることは明らかだと思います。

「malloc_size(ptr)関数は、ptrが指す割り当てをサポートするメモリブロックのサイズを返します。メモリブロックサイズは常に、少なくともそれがサポートする割り当てと同じ大きさであり、それよりも大きい場合があります。」 ( http://developer.Apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/malloc_size.3.html

ただし、辞書のサイズを知りたい場合は、次の点に注意してください。

ディクショナリはキーと値のペアを格納し、オブジェクト自体を値の部分にしないが含まれていますが、「追加され、それ自体でそのオブジェクトの参照を保持します。これで、ディクショナリ自体には、さまざまなオブジェクトへの参照が含まれています(キーが添付されています)。したがって、万が一、ディクショナリが参照するすべてのオブジェクトのオブジェクトサイズを探している場合、技術的にはディクショナリのサイズではありません。ディクショナリのサイズは、すべてのキーのサイズに、キーに対するすべての値参照のサイズに、親NSObjectのサイズを加えたサイズの合計になります。参照されているオブジェクトのサイズを確認することにも関心がある場合は、辞書の値の配列を繰り返してみてください。

NSArray *myArray = [myDictionary allValues];
id obj = nil;
int totalSize = 0;
for(obj in myArray)
{
    totalSize += malloc_size(obj);
}
//totalSize now contains the total object size of the refered objects in the dictionary.

それが質問に答えることを願っています。

14
Ameer Sheikh

(objective-c)オブジェクトのサイズは、定義するのも簡単ではないため、簡単に見つけることができません。 「objective-cオブジェクトのサイズ」とはどういう意味ですか?

参照のサイズは、(sizeof(obj_ref)によって返される)ポインターのサイズです。

作成時に割り当てられたメモリのサイズ(+ alloc)は、Jasonが最初の回答で与えた方法で見つけることができます。しかし、これはランタイムに依存します。 gnu-runtimeはApple-runtimeとは異なります。最終的にこれは、インスタンスを構成するプリミティブデータ型が必要とするメモリのみです。しかしnot ivarsまたは文字列によって参照されるオブジェクトに対して後で(つまり、初期化(-init)中に)割り当てることができるメモリ。

クラスのインスタンス

@interface FirstClass
{
    int _someInt;
    char _someChar;
}
…
@end

ランタイムで必要な場合は、少なくとも5バイト(多くのシステムではintサイズは異なる場合があります)と静的オーバーヘッドが必要です。そのようなオブジェクトのサイズは明白です。

しかし、クラスのインスタンスの場合

@interface SecondClass
{
    FirstClass *_someObject;
    char *_name;
    id _data;
}
…
@end

「サイズ」の定義は複雑ではありません。オブジェクトには12バイト(32ビットシステムの場合)と割り当てのオーバーヘッドが必要です。しかし、おそらく名前はオブジェクトの一部であり、オブジェクトによって割り当てられたり解放されたりします。実際の名前が必要とするメモリは、オブジェクトのサイズの一部である必要がありますか?そして、参照されたオブジェクトはどうですか?

7
Tilo Prütz

class_getInstanceSizemalloc_good_sizeを使用して、何が切り上げられるかを確認することをお勧めします。これは、返されたサイズ内のivarおよび何も表示しません。

#import <malloc/malloc.h>
#import <objc/runtime.h>

NSLog(@"Object Size: %zd", malloc_good_size(class_getInstanceSize([yourObject class])));
5
EvilPenguin