在objective-C对象接口中声明一个结构数组

时间:2013-08-03 14:13:41

标签: objective-c

我想声明一个简单的结构数组这是我的代码......但它不起作用:

@implementation GLPlane{
    GLKVector2 *vertices;
}

-(id)init{

    if(self = [super init]){
        vertices = {<---- This operation seems to be not allowed. 
            GLKVector2Make(0.0f, 0.5f),
            GLKVector2Make(-0.5f, 0.5f),
            GLKVector2Make(0.0f, 0.0f)
        };
    }
    return self;

}

问题出在哪里?

如果我以这种方式编写init函数,使用临时数组就可以了

-(id)init{

    if(self = [super init]){
        GLKVector2 tempArray[] = {
            GLKVector2Make(0.0f, 0.5f),
            GLKVector2Make(-0.5f, 0.5f),
            GLKVector2Make(0.0f, 0.0f)
        };

        vertices = tempArray;
    }

    return self;
}

4 个答案:

答案 0 :(得分:3)

GLKVector2 *vertices;

指针,而不是数组。您必须先分配内存然后才能分配 值:

vertices = calloc(3, sizeof(GLKVector2));
vertices[0] = GLKVector2Make(0.0f, 0.5f);
vertices[1] = GLKVector2Make(-0.5f, 0.5f);
vertices[2] = GLKVector2Make(0.0f, 0.0f);

ARC不管理此类分配,因此您应该释放dealloc中的内存:

- (void)dealloc 
{
    free(vertices);
}

请注意,您的第二个示例已编译,但不正确:vertices将是指向本地堆栈变量的指针,因此只要init方法返回就会无效。

答案 1 :(得分:1)

您应该使用NSValue类:

https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSValue_Class/Reference/Reference.html

您可以将结构包装到NSValue类对象,然后将其添加到数组

转换:

NSValue *anObj = [NSValue value:&vector withObjCType:@encode(GLKVector2)];
NSArray *array = [NSArray arrayWithObjects:anObj, nil];

Unconvert:

NSValue *anObj = [array objectAtIndex:0];
GLKVector2 vector;
[anObj getValue:&vector];

答案 2 :(得分:1)

首先,你正在做的事情会导致内存损坏,不要这样做。您正在堆栈上创建一个数组,并将其分配给一个变量,该变量的生命周期将长于数据有效的堆栈帧。您需要malloc空间(记住free中的dealloc!),并一次初始化一个元素(或创建一个临时数组并复制它)。或者,更好的是,使用NSArray的Igor's suggestion

现在,澄清让您感到困惑的数组行为(请注意,这些行为基于您发布的代码,因此受到上述堆栈分配问题的影响):

    vertices = {<---- This operation seems to be not allowed. 
        GLKVector2Make(0.0f, 0.5f),
        GLKVector2Make(-0.5f, 0.5f),
        GLKVector2Make(0.0f, 0.0f)
    };

不允许这样做的原因是编译器不知道您期望该数组的类型(C和Objective C不进行类型推断)。你能做的是告诉编译器数组的类型:

    vertices = (GLKVector2[]){
        GLKVector2Make(0.0f, 0.5f),
        GLKVector2Make(-0.5f, 0.5f),
        GLKVector2Make(0.0f, 0.0f)
    };

但是,作为一个特殊的例外,当你在声明中初始化一个数组时,编译器确实认为它是当前声明的类型,这就是为什么这样做的原因:

    GLKVector2 tempArray[] = {
        GLKVector2Make(0.0f, 0.5f),
        GLKVector2Make(-0.5f, 0.5f),
        GLKVector2Make(0.0f, 0.0f)
    };

    vertices = tempArray;

答案 3 :(得分:0)

您遇到的问题与您的结构没有任何关系,实际上是数组初始化方式的问题。使用此表示法创建数组时:

int myArr[] = {1, 3, 4, 5};

仅在声明数组并同时初始化时才有效。这是Java,C,C ++和Objective-C的情况。但是,您还有一个问题,那就是您声明了一个指针,并尝试向其添加项目。但是指针不是数组,例如:

int myOtherArr[5];
int *mySecondArr;

myOtherArrmySecondArr不同。为了将指针用作数组,您必须使用malloc或new或类似的东西将内存分配为数组。