2012-01-08 36 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