2010-11-26 1 views
0

Si je fais de mon objet une sous-classe de UIViewController, utilise-t-il beaucoup plus de mémoire que s'il s'agissait d'une sous-classe de NSObject? Un chiffre approximatif pour combien plus de frais généraux est utilisé en sous-classant une classe complexe par rapport à un simple serait super. edit: ou un moyen de comprendre la différence moi-même.Est-ce que tous les objets occupent des quantités de mémoire similaires? Objective-c

+0

Merci pour toutes les réponses impressionnantes! Super informatif !! –

Répondre

2

Vous pouvez imaginer qu'un objet c objectif est juste une structure C qui ressemble à ceci:

typedef struct { 
    Class isa; 
} NSObject; 

Une instance de cette structure prendrait 4 octets sur un système 32 bits. Comme il est composé d'un seul pointeur - Classe est similaire à l'ID.

Une sous-classe de NSObject, MaSousClasse avec une variable d'instance « char » ressemblerait à ceci:

typedef struct { 
    Class isa; 
    char singleInstanceVariable. 
} MySubclass; 

Une sous-classe a simplement toutes les variables d'instance de sa super-classe au début, plus propre à la fin. Vous pouvez le voir dans le débogueur en tapant 'p * object' dans la console.

La taille de MySubclass serait de 5 octets sur un système 32 bits. Un pointeur, plus un caractère. Ainsi, la taille d'un objet est la taille de toutes ses variables d'instance additionnées. Une chose importante à savoir est que la taille d'un objet n'est liée qu'à ses variables d'instance. Il n'est pas affecté par le nombre de méthodes dont il dispose. Ces méthodes ne coûtent pas de mémoire supplémentaire car plus d'instances sont instanciées. Les méthodes ont un coût initial fixe.

Une autre chose à prendre en compte est que les objets ont généralement des pointeurs vers d'autres objets en tant que variables d'instance. Par exemple, supposons que chaque UIView possède un NSMutableArray pour référencer ses sous-vues. Ce tableau peut avoir 12 octets lorsqu'il est vide. Donc, un UIView vide serait la taille de toutes les variables dans un UIView, ce qui inclurait 4 octets pour le pointeur sur un tableau, plus vous pourriez aussi prendre en compte les 12 octets supplémentaires utilisés par l'instance réelle du tableau. Tout cela n'est que comptabilité, le tableau et la vue sont deux objets distincts, mais la vue n'est pas vraiment utilisable sans le tableau.

Enfin, la plupart des allocations sont arrondies à un certain nombre afin de rendre l'implémentation de malloc plus rapide et de satisfaire certaines contraintes de l'architecture de la machine afin que les pointeurs soient correctement alignés. Aussi les variables d'instance d'un objet peuvent avoir un remplissage vide entre eux similaire à structure padding

2

Cela dépend du nombre et de la nature des variables d'instance de la superclasse. NSObject a un ivar, le pointeur isa. UIViewController a environ 30 ivars, la plupart d'entre eux pointeurs (vous pouvez regarder la liste en UIViewController.h).

Ainsi, toute sous-classe de UIViewController prendra autant de mémoire que nécessaire pour stocker tous les Ivars et tous Ivars de ses superclasses (UIResponder (pas Ivars) et NSObject (un Ivar)).

Ce calcul ne prend pas en compte la mémoire réelle utilisée par les objets référencés par ces variables d'instance lors de l'initialisation, bien entendu. Par exemple, un contrôleur de vue entièrement initialisé peut conserver un objet de vue qui occupe une quantité considérable de mémoire.

0

En bref, oui, mais probablement pas assez que vous devez vous en préoccuper à moins que vous ne prévoyiez d'instancier des dizaines de milliers d'entre eux.

L'objet allouera de la mémoire pour chacun de ses ivars et ses méthodes. La quantité de mémoire nécessaire dépend des types C ... ils varient tous en fonction du type de données stocké.

0

La quantité de mémoire utilisée dépend de la manière dont l'objet est instancié, présenté à l'écran et interagi avec. Par exemple, une sous-classe de NSObject n'aura aucune interaction avec les touches de l'utilisateur.

Vous pouvez toujours joindre votre application avec l'outil de performance Instruments Allocations pour comparer la différence.

+1

Un objet allouera toujours la même quantité de mémoire quand alloc'd, indépendamment de l'interaction avec lui. Certes, une partie de cette mémoire ne sera rien de plus qu'un pointeur vers la mémoire qui pourra être alloué plus tard (paresseux). Je ne suis pas sûr de ce que vous entendez par "comment l'objet est instancié"? L'interaction avec les touches de l'utilisateur n'a rien à voir avec l'utilisation de la mémoire. Les types de données que contient la définition de classe sont la seule chose qui affecte l'utilisation de la mémoire. – d11wtq

+0

un UIViewController initialisé à partir d'une plume aurait probablement une empreinte (légèrement) différente de celle initialisée dans le code ... non? –

+0

Tout objet identique allouera toujours la même quantité de mémoire. Par exemple, un tableau avec zéro objets utilisera moins de mémoire qu'un tableau contenant des éléments, mais deux tableaux créés avec les mêmes objets ou aucun objet utiliseront la même quantité de mémoire. De plus, tous les objets passés ou créés par cette classe utiliseront la mémoire jusqu'à ce qu'ils soient libérés. En plus de cela, toutes les notifications envoyées à cet objet/classe utilisent de la mémoire. –

2

Essayez class_getInstanceSize([MyClass class]);. Grosso modo, l'utilisation de la mémoire d'une instance sera cette valeur arrondie à un multiple de seize octets. Bien sûr, cela n'inclut pas les frais généraux des objets associés (voir objc_setAssociatedObject) ou les affectations effectuées par la classe.

Questions connexes