Как инициализировать массив постоянных членов C в классе Objective-C? - PullRequest
3 голосов
/ 30 сентября 2011

как я могу создать постоянный член массива C в классе Objective-C? Жизненный цикл должен быть ограничен жизненным циклом классов, и я не хочу использовать malloc.

На данный момент я делаю это:

@interface Bla
{
    int myArray[3];
}

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

Но я хочу, чтобы он был постоянным и инициализировал его напрямую, например:

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

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

Ответы [ 2 ]

2 голосов
/ 09 октября 2011

вы можете использовать подход C и использовать постоянный массив в вашем .m:

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

время жизни этого массива - это продолжительность программы, и для него не требуется malloc или хранилище для каждого экземпляра.

в противном случае, на самом деле не существует такого понятия, как постоянное значение для переменных типа objc (если вы не довольны неизменяемой нулевой памятью). лучшее, что вы можете сделать, это сделать ivar приватным, а не предоставлять сеттер. const ivar также не имеет применимости много , так как в этом случае компилятор может оптимизировать немного. конечно, вы можете выбросить константу, но это плохая идея.

один последний вариант: вы можете использовать экземпляр c ++, который создается с помощью конструктора по умолчанию.

в противном случае вам придется использовать динамическое распределение для создания динамически заполненной переменной-члена const.

0 голосов
/ 09 октября 2011

Как правило, вы не должны ставить фигурные скобки вокруг @implementation. По поводу вашего вопроса: проблема, которую я вижу в том, как вы пытаетесь назначить вам массив, имеет следующую ошибку:

Когда вы инициализируете новый экземпляр ObjC объекта, его переменные экземпляра устанавливаются в ноль, поэтому ваш массив будет иметь вид [0] == a [1] == a [2] == 0. Это потому, что распределитель спросит у кучи памяти размер вашего объекта + его предков. Но позже в коде вы пытаетесь скопировать память из стека в кучу: массив {4, 5, 6} создается в стеке, а массив [] живет в куче. Вы видите проблему здесь? Что бы я сделал, если бы вы настаивали на этом, было бы следующее:

// 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;
}

Это не лучший способ, и, вероятно, вы захотите использовать malloc, но таким образом вам не придется освобождать массив позже. Также имейте в виду, что если вы сделаете это таким образом, вы не сможете изменить размер массива [], это наверняка приведет к проблемам:)

...