Проверка размера объекта в Objective-C - PullRequest
35 голосов
/ 17 апреля 2009

Я пытаюсь найти размер объекта target-c. Я использую что-то похожее на:

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

Это просто дает мне размер указателя.

Что я делаю не так?

Ответы [ 6 ]

51 голосов
/ 18 апреля 2009

Все, что знает компилятор, это указатель, поэтому вы получаете размер указателя обратно. Чтобы увидеть размер выделенного объекта, используйте один из следующих фрагментов кода:

с ARC:

#import <malloc/malloc.h>

// ...

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

без дуги:

#import <malloc/malloc.h>

// ...

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

В своем блоге вопросов и ответов у Майка Эша есть примечательная статья о некоторых внутренних компонентах Obj-C: http://mikeash.com/?page=pyblog/friday-qa-2009-03-13-intro-to-the-objective-c-runtime.html

19 голосов
/ 18 апреля 2009

Во время выполнения GNU Objective-C вы можете использовать (вы должны импортировать <objc/objc-api.h>:

class_get_instance_size ([MyClass class]);

В Mac OS X вы можете использовать (вам может потребоваться импортировать <objc/runtime.h>):

class_getInstanceSize ([MyClass class]);

Эти функции будут возвращать, сколько памяти требуется для выделения объекта, но не включают память, выделенную объектом при инициализации.

13 голосов
/ 17 сентября 2010

Прежде всего, я думаю, что из приведенных выше сообщений ясно, что размер объекта задается malloc_size (myObject), как это было предложено Джейсоном, а также в справочном руководстве Mac OS:

"Функция 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.

Надеюсь, что ответит на вопрос.

7 голосов
/ 18 апреля 2009

Размер объекта (target-c) найти нелегко, поскольку его даже нелегко определить. Что вы имели в виду под "размером объекта объектива-с"?

Размер ссылки - это размер указателя (который возвращается sizeof (obj_ref)).

Размер памяти, который был выделен при создании (+ alloc), может быть найден по тому, что Джейсон дал в первом ответе. Но это зависит от времени выполнения. Время выполнения GNU отличается от времени выполнения Apple. В конечном счете это только память, которая необходима для примитивных типов данных, из которых состоит экземпляр. Но не память, которая может быть выделена позже (то есть во время инициализации (-init)) для объектов, на которые ссылаются ivars или строки.

Экземпляр класса

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

требуется не менее 5 байт (во многих системах размер int может варьироваться) плюс статические издержки, если это требуется среде выполнения. Размер такого объекта очевиден.

Но для экземпляра класса

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

Определение «размера» очень сложно. Объекту требуется 12 байтов (в 32-битных системах) плюс накладные расходы на выделение. Но, возможно, имя является частью объекта и выделяется / освобождается им. Должна ли память, которой нужно фактическое имя, быть частью размера объекта? А как насчет объектов, на которые есть ссылки?

4 голосов
/ 28 января 2013

Я бы предложил использовать class_getInstanceSize и malloc_good_size, чтобы посмотреть, к чему это приведет. Это не будет отображать ивары и еще много чего в возвращенном размере.

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

NSLog(@"Object Size: %zd", malloc_good_size(class_getInstanceSize([yourObject class])));
0 голосов
/ 18 апреля 2009

Я думаю, что описание класса содержит информацию о размере - лучше посмотреть это, чем запросить оператор sizeof.

...