3 votes

Comment initialiser un tableau C membre constant dans une classe Objective-C ?

Comment créer un membre constant de tableau C dans une classe Objective-C ? Le cycle de vie doit être limité au cycle de vie de la classe et je ne veux pas utiliser malloc.

En ce moment, c'est ce que je fais :

@interface Bla
{
    int myArray[3];
}

@implementation Bla
{
    -(id)init
    {
        myArray[1] = 5;
        myArray[2] = 6;
        myArray[3] = 7;
        return self;
    }
}

Mais je la veux constante et l'initialiser directement, comme :

@interface Bla
{
    const int myArray[3];
}

@implementation Bla
{
    -(id)init
    {
        myArray[] = { 5, 6, 7 };
        return self;
    }
}

2voto

justin Points 72871

Vous pourriez adopter l'approche C et utiliser un tableau constant dans votre fichier .m :

static const int myArray[3] = { 5, 6, 7 };

la durée de vie de ce tableau est la durée du programme, et il ne nécessite pas de malloc ou de stockage par instance.

autrement, il n'existe pas vraiment de valeur constante pour les variables d'un type d'objc (à moins que vous ne vous contentiez d'une mémoire immuable mise à zéro). le mieux que vous puissiez faire est de rendre l'ivar privée et de ne pas fournir de setter. une ivar const n'a pas de valeur constante. beaucoup Il n'y a pas non plus d'applicabilité, car il y a peu d'optimisations que le compilateur pourrait faire dans ce cas. Bien sûr, vous pourriez supprimer la constance, mais c'est une mauvaise idée.

une dernière alternative : vous pouvez utiliser une instance c++ qui est créée en utilisant son constructeur par défaut.

sinon, vous devrez utiliser une allocation dynamique pour créer une variable membre const alimentée dynamiquement.

-1voto

funkaster Points 137

Par convention, vous ne devez pas mettre d'accolades autour de @implementation. A propos de votre question : le problème que je vois avec la façon dont vous essayez d'assigner votre tableau a l'erreur suivante :

Quand vous initialisez une nouvelle instance ObjC d'un objet, ses variables d'instance sont mises à zéro, donc votre tableau sera a[0] == a[1] == a[2] == 0. C'est parce que l'allocateur demandera de la mémoire de tas de la taille de votre objet + ses ancêtres. Mais plus tard dans le code, vous essayez de copier la mémoire de la pile vers le tas : le tableau {4, 5, 6} est créé sur la pile, et le tableau[] vit sur le tas. Vous voyez le problème ici ? Ce que je ferais, si vous insistez pour le faire de cette façon, serait le suivant :

// compile from command line with
// gcc -framework Foundation -g -Wall -o test test.m
//
#import <Foundation/Foundation.h>

@interface  Bla : NSObject
{
    int array[3];
}

- (void)checkArray;
@end

@implementation Bla
- (id)init
{
    self = [super init];
    if (self) {
        // init here
        int tmpArray[3] = { 4, 5, 6};
        memcpy(array, tmpArray, 3 * sizeof(int));
    }
    return self;
}

- (void)checkArray
{
    NSAssert(array[0] == 4, @"invalid array initialization (4)");
    NSAssert(array[1] == 5, @"invalid array initialization (5)");
    NSAssert(array[2] == 6, @"invalid array initialization (6)");
}
@end

int main() {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    {
        Bla *bla = [[Bla alloc] init];
        [bla checkArray];
        NSLog(@"done");
        [bla release];
    }
    [pool release];
    return 0;
}

Ce n'est pas la meilleure méthode, et vous devriez probablement vous en tenir à l'utilisation de malloc, mais de cette façon vous n'aurez pas à libérer le tableau plus tard. Gardez également à l'esprit qu'en procédant de cette manière, vous ne pourrez pas modifier la taille du tableau[], ce qui vous causera des problèmes à coup sûr :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X