2009-01-08 4 views
3

Considérez ce qui suit:Sur quel type de mémoire une struct C est attribuée lorsque initialisé comme une variable de classe en Objective-C

typedef struct 
{ 
    float m00, m01, m02, m03; 
    float m10, m11, m12, m13; 
    float m20, m21, m22, m23; 
    float m30, m31, m32, m33; 
} Matrix; 

@interface TestClass : NSObject 
{ 
    Matrix matrix; 
} 

- (TestClass *) init; 
@end 

@implementation TestClass 
- (TestClass *) init 
{ 
    self = [super init]; 
    matrix = (Matrix) {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; 
    return self; 
} 
@end 

Comment faire en sorte que les 64 octets alloués à la struct sont correctement libérés chaque fois que la variable "matrix" n'est plus pertinente (ou chaque fois que l'objet entier est libéré)?

+0

Vous pouvez reformuler le titre de votre question. – lillq

+0

Le titre est parfaitement logique pour moi ... –

+0

Vous devriez dire "instance variable" au lieu de "class variable" en fait. – Blaisorblade

Répondre

6

Dans ce cas, la matrice doit être être incorporée dans la structure générée par le compilateur ObjectiveC pour les instances de TestClass. Sa durée de vie est liée à l'instance de TestClass dont il fait partie, tout comme un membre int ou float.

Vous pouvez facilement tester ceci, si vous inspectez les pointeurs.

TestClass* testAddress = [[TestClass alloc] init]; 
Matrix* matrixAddress = &(testAddress->matrix); 

int rawTest = (int) testAddress; 
int rawMatrix = (int) matrixAddress; 
int memberOffset = rawMatrix - rawTest; 

printf("%i", memberOffset); 

J'ai pas compilateur ici, mais je suppose que ce sera juste marmonner quelques avertissements au sujet du mal typecasts et générer le code de toute façon. La sortie doit être constante, de l'ordre de 4 ou 8, en fonction de votre architecture cible.

+0

Bingo! (une structure à l'intérieur d'une structure a du sens pour moi maintenant ...) –

3

Dans ce cas, vous n'avez absolument rien à faire avec la structure pour libérer sa mémoire lorsque l'objet qui la contient est désalloué. La mémoire de la structure est en ligne dans l'objet.

1

En aparté, le CATransform3D de Core Animation a la même structure interne que votre matrice:

struct CATransform3D 
    { 
    CGFloat m11, m12, m13, m14; 
    CGFloat m21, m22, m23, m24; 
    CGFloat m31, m32, m33, m34; 
    CGFloat m41, m42, m43, m44; 
}; 

Au lieu de définir un type personnalisé, vous pouvez utiliser celui-ci fourni par Apple. Apple fournit également des fonctions très pratiques pour manipuler ces matrices.

+0

Bon à savoir mais les fonctions de matrice que je prévois d'utiliser sont plus adaptées dans le contexte d'OpenGL ES sur l'IPhone ... –

+0

Core Animation est soutenu par OpenGL, donc je crois que la manipulation de la matrice fonctionne comme CATransform3DRotate directement aux opérations équivalentes de la matrice de vue du modèle OpenGL. –

+0

OpenGL ES ne signifie aucune manipulation de vertex "mode direct", vous finissez par être celui qui transforme le vertice (les opérations matricielles OpenGL ne peuvent pas aider ici) et dans ce cas: vous avez besoin de fonctions mathématiques matricielles optimisées - par ex. rotateX (angle) - qui ne sont généralement pas disponibles dans les bibliothèques standard ... –

Questions connexes