Подтвердить что ты не робот

Проверка размера объекта в Objective-C

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

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

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

Что я делаю неправильно?

4b9b3361

Ответ 1

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

С 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));

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

Ответ 2

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

class_get_instance_size ([MyClass class]);

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

class_getInstanceSize ([MyClass class]);

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

Ответ 3

Прежде всего, я думаю, что из вышеуказанных сообщений ясно, что размер объекта задан 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.

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

Ответ 4

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

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

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

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

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

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

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

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

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

Ответ 5

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

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

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

Ответ 6

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