2012-01-08 69 views
1

我已經搜索並找不到斷言。我知道這是我在這裏想念的一件基本的事情。客體C枚舉類型在重新分配對象變化

我有一個枚舉:

typedef enum { 
    NINETYBEND, NINETYBEND_FAST, NINETYBEND_SLOW, STRAIGHT 
} BlockTypeEnum; 

我想在我創造這樣的對象來使用這些值:發生

BlockTypeEnum blockType = STRAIGHT; 
XMLLevelPiece* piece = [[XMLLevelPiece alloc] init]; 
[piece initPiece:blockType]; 

我的問題,當我嘗試使用同一個變量兩次。如果我使用枚舉創建一個對象,更改枚舉,然後使用它創建第二個對象,則第一個對象中的枚舉將更改爲第二枚舉值。這不是我想要的。實施例下面:

BlockTypeEnum blockType = STRAIGHT; 

XMLLevelPiece* piece = [[XMLLevelPiece alloc] init]; 
[piece initPiece:blockType]; 

blockType = NINETYBEND_FAST; 

XMLLevelPiece* piece2 = [[XMLLevelPiece alloc] init]; 
[piece2 initPiece:blockType]; 

NSLog([NSString stringWithFormat:@"%d", [piece getBlockType]]); 
NSLog([NSString stringWithFormat:@"%d", [piece2 getBlockType]]); 

//BOTH BLOCK TYPES ARE NOW NINETYBEND_FAST, NOT WHAT I WANTED!! 

據我理解,枚舉只是一個美化了INT,而不是一個指針,我加入到所述第一對象之後重新分配該變量。請有人能告訴我我錯過了什麼!謝謝,西蒙。

這是我的XMLPiece代碼,謝謝!

#import "XMLLevelPiece.h" 
#import "BlockType.h" 
#import "GridCord.h" 
#import "BlockColor.h" 

@implementation XMLLevelPiece 

BlockTypeEnum mBlockType; 
BlockColorEnum mBlockColor; 
int mRotation; 
GridCord* mGridCords; 
BlockColorEnum mLeftColor; 
BlockColorEnum mTopColor; 
BlockColorEnum mRightColor; 
Boolean mRotatable; 
Boolean mMoveable; 
int mGroupID; 

-(id) init 
{ 
    if((self=[super init])) { 

    } 
    return self; 
} 

-(void)initPiece:(BlockTypeEnum)pBlockType pBlockColor:(BlockColorEnum)pBlockColor pRotation:(int)pRotation pGridCords:(GridCord*)pGridCords pLeftColor:(BlockColorEnum) pLeftColor pTopColor:(BlockColorEnum) pTopColor pRightColor:(BlockColorEnum) pRightColor pRotatable:(Boolean) pRotatable pMoveable:(Boolean) pMoveable pGroupID:(int) pGroupID 
{ 
    mBlockType = pBlockType; 
    mBlockColor = pBlockColor; 
    mRotation = pRotation; 
    mGridCords = pGridCords; 
    mLeftColor = pLeftColor; 
    mTopColor = pTopColor; 
    mRightColor = pRightColor; 
    mRotatable = pRotatable; 
    mMoveable = pMoveable; 
    mGroupID = pGroupID; 
} 

-(void)initPiece2 
{ 
    NSLog(@"poo"); 
} 

-(Boolean)getRotatable 
{ 
    return mRotatable; 
} 

-(Boolean)getMoveable 
{ 
    return mMoveable; 
} 

-(int) getGroupID 
{ 
    return mGroupID; 
} 

-(BlockColorEnum) getLeftColor 
{ 
    return mLeftColor; 
} 

-(BlockColorEnum) getTopColor 
{ 
    return mTopColor; 
} 

-(BlockColorEnum) getRightColor 
{ 
    return mRightColor; 
} 

-(BlockTypeEnum) getBlockType 
{ 
    return mBlockType; 
} 

-(BlockColorEnum) getBlockColor 
{ 
    return mBlockColor; 
} 

-(int) getRotation 
{ 
    return mRotation; 
} 

-(id) getGridCords 
{ 
    return mGridCords; 
} 

-(void) setRotatable:(Boolean) pRotatable 
{ 
    mRotatable = pRotatable; 
} 

-(void) setMoveable:(Boolean) pMoveable 
{ 
    mMoveable = pMoveable; 
} 

@end 
+0

什麼方法'getBlockType'是什麼樣子? – 2012-01-08 15:08:00

+0

我們確實需要查看XMLLevelPiece的代碼,請編輯您的問題以提供相關信息。 – zaph 2012-01-08 15:08:25

+0

我很確定調用'init'然後'initPiece'不是你想要的。你應該最有可能擁有' - (id)initWithPiece:(BlockTypeEnum)blockType;'它會在它的實現中調用'[super init]'。 – 2012-01-08 15:10:04

回答

1

TL; DR

答案是 - 這不是你如何定義在Objective-C的ivars。我甚至不知道這應該如何表現,但我可以重現錯誤,如果我把它編碼一樣,你有。

我會對有更多知識的人感興趣,以解釋這些變量的行爲/範圍應該如何定義。


有在該代碼

很多缺陷的你有沒有實際顯示的initPiece:

帶有所有參數的長init...可能是一個壞主意。通常只需要將一些東西添加到init中,以方便使用,或者如果沒有它,對象就無法正常工作。

使用的get是不是真的正確在Objective-C

類應該可能更像

XMLLevelPiece.h

// You will need to import the header with the BlockTypeEnum defined 

@interface XMLLevelPiece : NSObject 

@property (nonatomic, assign) BlockTypeEnum blockType; 
// .. Other properties 

- (id)initWithPiece:(BlockTypeEnum)blockType; // I'm not so sure you need this 

@end 

XMLLevelPiece.m

定義
#import "XMLLevelPiece.h" 
#import "BlockType.h" 
#import "GridCord.h" 
#import "BlockColor.h" 

@implementation XMLLevelPiece 

@synthesize blockType = mBlockType; 

- (id)initWithPiece:(BlockTypeEnum)blockType; 
{ 
    self = [super init]; 
    if (self) { 
     mBlockType = blockType; 
    } 
    return self; 
} 

@end 

然後你可以使用它像

BlockTypeEnum blockType = STRAIGHT; 

XMLLevelPiece *p1 = [[XMLLevelPiece alloc] initWithPiece:blockType]; 

blockType = NINETYBEND_FAST; 

XMLLevelPiece *p2 = [[XMLLevelPiece alloc] initWithPiece:blockType]; 

NSLog(@"%d", p1.blockType); 
NSLog(@"%d", p2.blockType); 

我結果,其中:

2012-01-08 15:29:31.782 Untitled[1297:707] 3 
2012-01-08 15:29:31.791 Untitled[1297:707] 1 

可選觀察

如果你可以用專用的初始化做掉,用法看起來更像:

BlockTypeEnum blockType = STRAIGHT; 

XMLLevelPiece *p1 = [[XMLLevelPiece alloc] init]; 
p1.blockType = blockType; 
// all other assignments 

blockType = NINETYBEND_FAST; 

XMLLevelPiece *p2 = [[XMLLevelPiece alloc] init]; 
p2.blockType = blockType; 
// all other assignments 

NSLog(@"%d", p1.blockType); 
NSLog(@"%d", p2.blockType); 

要刪除幾個superflous線,你可以刪除本地blockType變量和值分配直奔對象:

XMLLevelPiece *p1 = [[XMLLevelPiece alloc] init]; 
p1.blockType = STRAIGHT; 
+0

嗨。感謝那。我知道它非常糟糕的代碼,我打算使用屬性進行重構。我正在做一個來自java的端口,並遇到了描述的問題。雖然在那裏有很多不好的做法,但我仍然不明白是什麼導致了這個問題。我想我應該重構使用你的建議,並儘量不要擔心它:)謝謝西蒙 – 2012-01-08 15:47:20

+0

那麼問題是,這不是你如何定義在Objective-C中的Ivars。我甚至不知道該如何表現,但如果我將它編碼爲與您相同,我可以重現該錯誤。 – 2012-01-08 15:52:41

+0

非常感謝。我重構了班級,所有工作都按預期工作。學習我的課程,使用該語言的約定。它扔了我,因爲我做了這些類的直接端口,並沒有看到邏輯上的差異。我會花一整天時間重構其餘的部分。再次感謝,西蒙。 – 2012-01-08 16:10:46

1

您的方法調用initWithPiece與定義不符。

電話:

[piece initPiece:blockType]; 

定義:

-(void)initPiece:(BlockTypeEnum)pBlockType pBlockColor:(BlockColorEnum)pBlockColor pRotation:(int)pRotation pGridCords:(GridCord*)pGridCords pLeftColor:(BlockColorEnum) pLeftColor pTopColor:(BlockColorEnum) pTopColor pRightColor:(BlockColorEnum) pRightColor pRotatable:(Boolean) pRotatable pMoveable:(Boolean) pMoveable pGroupID:(int) pGroupID 

評論:

一般方法與以上幾個參數,最好在一個貧窮的想法調用。在這種情況下可能更好的是使用單個設置器。

Objective-C中按照Apple的慣例是命名不帶「get」前綴的getter。實際上,get前綴表示通過引用參數返回的值,而不是返回結果。這種用法會混淆分析儀,如果使用ARC會導致問題。

+0

嗨。對不起,我在第一個代碼示例中減少了定義,以便更清楚地說明問題所在。我目前正在移植一個Android項目,因此無法重構因此獲得者。我正在使用ARC,所以我嘗試將getBlockType重命名爲BlockType,但我仍然遇到同樣的問題。我不知道在名稱中使用'get'可能會導致問題,所以非常感謝。不幸的是,它似乎不是問題。 – 2012-01-08 15:36:07

+0

而不是'getBlockType',通常的編碼就是'blockType'。 setter方法將被命名爲:'setBlockType'。這不是你的錯誤,只是希望「有幫助的提示」。 – zaph 2012-01-08 15:41:35