tiempo - Verificar el tamaño de un objeto en Objective-C
swift lenguaje de programación (6)
Creo que la descripción de la clase contiene información sobre el tamaño: es mejor buscar esto que consultar con el operador sizeof
.
Estoy tratando de encontrar el tamaño de un objeto objetivo-c. Estoy usando algo similar a:
NSLog(@"sizeof myObject: %ld", sizeof(*myObject));
Sin embargo, eso me da el tamaño del puntero.
¿Qué estoy haciendo mal?
El tamaño de un objeto (objetivo-c) no es fácil de encontrar porque no es fácil de definir. ¿Qué quisiste decir con "tamaño de un objeto objetivo c"?
El tamaño de la referencia es el tamaño de un puntero (como lo devuelve sizeof (obj_ref)).
El tamaño de la memoria asignada en la creación (+ alloc) se puede encontrar por la forma en que Jason dio la primera respuesta. Pero esto depende del tiempo de ejecución. El gnu-runtime difiere del tiempo de ejecución de apple. Finalmente, esta es solo la memoria que necesitan los tipos de datos primitivos en los que está compuesta la instancia. Pero no la memoria que puede asignarse más tarde (es decir, durante la inicialización (-init)) para los objetos a los que hacen referencia los ivars o las cadenas.
Una instancia de la clase
@interface FirstClass
{
int _someInt;
char _someChar;
}
…
@end
necesita al menos 5 bytes (en muchos sistemas, el tamaño int
puede variar) más sobrecarga estática si el tiempo de ejecución lo necesita. El tamaño de tal objeto es obvio.
Pero para una instancia de la clase
@interface SecondClass
{
FirstClass *_someObject;
char *_name;
id _data;
}
…
@end
la definición del "tamaño" es complicada. El objeto necesita 12 bytes (en sistemas de 32 bits) más una sobrecarga en la asignación. Pero tal vez el nombre es parte del objeto y asignado / liberado por él. ¿Debería la memoria que el nombre real necesita ser parte del tamaño del objeto? ¿Y los objetos referenciados?
En el tiempo de ejecución de GNU Objective-C, puede usar (debe importar <objc/objc-api.h>
:
class_get_instance_size ([MyClass class]);
En Mac OS X puede usar (puede que necesite importar <objc/runtime.h>
):
class_getInstanceSize ([MyClass class]);
Estas funciones devolverán cuánta memoria se requiere para asignar un objeto, no incluirá la memoria asignada por un objeto cuando se inicialice.
En primer lugar, creo que está claro en las publicaciones anteriores que el tamaño del objeto está dado por malloc_size (myObject), como lo sugiere Jason y también en el manual de referencia de Mac OS:
"La función malloc_size ( ptr ) devuelve el tamaño del bloque de memoria que respalda la asignación apuntada por ptr . El tamaño del bloque de memoria siempre es al menos tan grande como la asignación que respalda, y puede ser mayor". ( http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/malloc_size.3.html )
Pero si está interesado en conocer el tamaño del diccionario, tenga en cuenta el siguiente punto:
El diccionario almacena pares clave-valor y no contiene el objeto en sí en la parte de valor, sino que simplemente aumenta un conteo retenido del objeto que se iba a "agregar" y mantiene una referencia de ese objeto consigo mismo. Ahora, el diccionario mismo contiene las referencias a los diversos objetos (con una clave adjunta). Entonces, si por casualidad está buscando el tamaño del objeto de todos los objetos a los que hace referencia el diccionario, técnicamente ese no sería el tamaño del diccionario. El tamaño del diccionario sería la suma del tamaño de todas las teclas más el tamaño de todas las referencias de valor contra las teclas más el tamaño del NSObject padre. Si todavía está interesado en conocer el tamaño de los objetos referidos también, intente iterar sobre la matriz de valores del diccionario:
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.
Espero que responda la pregunta.
Sugiero utilizar class_getInstanceSize
y malloc_good_size
para ver qué va a hacer. Esto no mostrará los ivars y whatnot dentro del tamaño devuelto.
#import <malloc/malloc.h>
#import <objc/runtime.h>
NSLog(@"Object Size: %zd", malloc_good_size(class_getInstanceSize([yourObject class])));
Todo lo que sabe el compilador es el puntero, por lo que recuperas el tamaño del puntero. Para ver el tamaño del objeto asignado, use uno de los siguientes fragmentos de código:
Con ARC:
#import <malloc/malloc.h>
// ...
NSLog(@"Size of %@: %zd", NSStringFromClass([myObject class]), malloc_size((__bridge const void *) myObject));
Sin ARC:
#import <malloc/malloc.h>
// ...
NSLog(@"size of myObject: %zd", malloc_size(myObject));
Mike Ash tiene una reseña decente sobre algunos de los aspectos internos de ejecución de Obj-C en su blog de preguntas y respuestas: http://mikeash.com/?page=pyblog/friday-qa-2009-03-13-intro-to-the-objective-c-runtime.html