2013-08-03 25 views
1

我要聲明結構的簡單數組這是我的代碼...但它不工作:聲明結構數組中的客觀-C objecti接口

@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; 

} 

問題出在哪裏?

如果我寫的初始化函數的方式,用它工作

-(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; 
} 
+1

賦值不是初始化。 – 2013-08-03 14:15:23

+0

你的錯誤是什麼? – eswick

+0

我已經添加了一些更多信息。錯誤是'期望的表達式' – MatterGoal

回答

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

臨時數組你應該使用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]; 
+1

對於基於性能的OpenGL調用,這是一個糟糕的想法。它比用malloc創建的純C數組慢得多。 –

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; 
+0

在上面的兩個例子中,請注意該數組將被分配到堆棧上,並且在堆棧框架「彈出」之後,您將丟失數組。 –

+0

@ RichardJ.RossIII是的,這些例子只是爲了解釋,而不是我在第一段中描述的修復。我已經爲此澄清了。 – Kevin

0

你正面臨着沒有任何與您的結構實際上是在與你的數組初始化的方式有問題的問題。使用這種表示法創建陣列時:

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

它只在聲明數組並同時初始化它時才起作用。 Java,C,C++和Objective-C就是這種情況。然而,你還有一個問題,那就是你聲明瞭一個指針,並且他們嘗試向它添加項目。但有指針不是數組,例如:

int myOtherArr[5]; 
int *mySecondArr; 

myOtherArr是不一樣的mySecondArr。爲了使用指針作爲數組,你必須使用malloc或新的或類似的東西來將內存分配爲一個數組。