Тип перечисления Objective C в объекте, изменяющемся при переназначении - PullRequest
1 голос
/ 08 января 2012

Я искал и не могу найти подтверждения этому. Я знаю, что это фундаментальная вещь, которую я здесь скучаю.

У меня есть перечисление:

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!!

Насколько я понял, enum - это просто прославленный 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

Ответы [ 2 ]

1 голос
/ 08 января 2012

TL; DR

Ответ - это не то, как вы определяете ivars в Objective-C. Я даже не уверен, как это должно себя вести, но я могу воспроизвести ошибку, если кодирую ее так же, как вы.

Мне было бы интересно, чтобы кто-то, обладающий большими знаниями, объяснил, каким должно быть поведение / область действия этих переменных, когда они определены, как у вас.


В этом коде много недостатков

Вы на самом деле не показали 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);

Чтобы удалить пару лишних строк, вы можете удалить локальную переменную blockType и присвоить значение прямо объекту:

XMLLevelPiece *p1 = [[XMLLevelPiece alloc] init];
p1.blockType = STRAIGHT;
1 голос
/ 08 января 2012

Ваш вызов метода для 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. Фактически префикс get означает значение, возвращаемое через ссылочный параметр, а не как возвращаемый результат. Такое использование может сбить с толку анализатор и вызвать проблемы при использовании ARC.

...