如何在Objective-C类中初始化常量成员C数组?

3

如何在Objective-C类中创建常量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
顺便提一下,C 数组是从零开始的,而不是从一开始。所以你的代码应该是:myArray[0] = 5; myArray[1] = 6; myArray[2] = 7; - EricS
2
你为什么不想使用malloc? - Sean
因为这样我就必须分配两次内存。一次使用malloc,另一次使用临时数组来填充动态分配的内存。如果我错了,请纠正我。 - user973224
在这个例子中,myArray的生命周期会有多长?@implementation Bla { const float myArray[] = { 5, 6, 7 }; } - user973224
当您的对象仍然存在时。 - Nekto
显示剩余3条评论
2个回答

2
您可以采用C语言的方法,在.m文件中使用一个常量数组:
static const int myArray[3] = { 5, 6, 7 };

该数组的生存期为程序的持续时间,不需要malloc或各个实例的存储。

否则,对于objc类型变量来说,真正的常量值其实并不存在(除非您满意于不可变的零内存)。最好的方法是将实例变量设置为私有,并且不提供setter方法。const实例变量在这种情况下几乎没有什么适用性,因为编译器可以进行的优化很少。当然,您可以强制转换去掉const属性,但这是一个坏主意。

最后一个选择是:可以使用C++实例,该实例使用其默认构造函数创建。

否则,您将不得不使用动态分配来创建动态填充的const成员变量。


-1

作为一种惯例,你不应该在 @implementation 周围放置花括号。

关于你的问题:我看到你尝试分配数组的方式存在以下错误:

当你初始化一个新的 ObjC 实例对象时,它的实例变量会被设置为零,所以你的数组将是 a[0] == a[1] == a[2] == 0。这是因为分配器会要求堆内存大小等于你的对象加上其祖先的大小。但是在代码的后面,你尝试从栈复制内存到堆:{4,5,6} 数组是在栈上创建的,而 array[] 存在于堆上。你看到这里的问题了吗?如果你坚持这样做,我会这样做:

// 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,但这样做你就不必后来释放数组。另外,请记住,用这种方式,您将无法更改array[]的大小,这样做肯定会有麻烦 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接