1

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

@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

4 回答 4

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方法返回就无效。

于 2013-08-03T15:20:20.200 回答
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];

取消转换:

NSValue *anObj = [array objectAtIndex:0];
GLKVector2 vector;
[anObj getValue:&vector];
于 2013-08-03T14:38:29.053 回答
1

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

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

    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;
于 2013-08-03T15:22:33.667 回答
0

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

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

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

int myOtherArr[5];
int *mySecondArr;

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

于 2013-08-03T16:13:07.730 回答