【问题标题】:How to initialize constant member C array in an Objective-C class?如何在 Objective-C 类中初始化常量成员 C 数组?
【发布时间】:2011-09-30 14:17:44
【问题描述】:

如何在 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;
    }
}

【问题讨论】:

  • 顺便说一句,C 数组是从零开始的,而不是从一开始的。所以你的代码应该是: myArray[0] = 5;我的数组[1] = 6;我的数组[2] = 7;
  • 你为什么不想使用 malloc?
  • 因为那时我必须分配两次内存。一个带有 malloc 和一个额外的临时数组来提供动态分配的内存。如果我错了,请纠正我。
  • 在这个例子中 myArray 的生命周期是多久? @implementation Bla { const float myArray[] = { 5, 6, 7 }; }
  • 当你的对象还活着时。

标签: objective-c c arrays initialization constants


【解决方案1】:

您可以采用 C 方法并在 .m 中使用常量数组:

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

这个数组的生命周期是程序的持续时间,它不需要 malloc 或每个实例的存储空间。

否则,对于 objc 类型的变量,实际上没有常量值这样的东西(除非您满足于不可变的零内存)。您能做的最好的事情就是将 ivar 设为私有而不提供 setter。 const ivar 也没有 太多 适用性,因为在这种情况下编译器可以进行的优化很少。当然,你可以抛弃 constness,但这是个坏主意。

最后一种选择:您可以使用使用其默认构造函数创建的 c++ 实例。

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

【讨论】:

    【解决方案2】:

    按照惯例,您不应该在@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[] 的大小,这样做肯定会遇到麻烦:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-25
      • 2011-09-08
      • 1970-01-01
      • 2019-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多