0

I am new to programming with Objective-C and Stackoverflow, and I need some help.

I'm trying to get an object from a NSMutableArray and check one of its internal properties. I figured the best way to do this is by doing the following cast:

GenericRoom *room = (GenericRoom*)[myRooms objectAtIndex: currentIndex + side];

if (room.myType == EMPTY) {
    return YES;
}

The problem is that when I create a class of type GenericRoom, your constructor already defines myType as EMPTY. When I insert the instances in NSMutrableArray, I changed to myType TAVERN this way:

NSMutableArray *myRooms = [[NSMutableArray alloc] initWithCapacity:15];

for (int i = 0: i <15: i + +) {
    GenericRoom tmpRoom * = [[GenericRoom alloc] initWithType: TAVERN];
    myRooms insertObject: tmpRoom atIndex i];
}

But when I do the cast that quote up there, it simply creates a new instance of the object GenericRoom, instead of copying the object inside NSMutableArray, making its result is always YES, my failing vereficação.

Is there any better way to solve this problem? Thank you all.

EDIT: The complete code

GenericRoom.h

#import <Foundation/Foundation.h>
#import "cocos2d.h"

enum Rooms {
    EMPTY, TAVERN, WARRIORGUILD, MAGEGUILD
}roomsType;

@interface GenericRoom : CCLayer {
    CCSprite *mySprite;
    enum Rooms myType;
}

@property (nonatomic, retain) CCSprite *mySprite;
@property enum Rooms myType;
@property int test;

- (id)initWithSprite: (NSString *)file;
- (id)initWithType: (enum Rooms)roomType;

@end

GenericRoom.m

#import "GenericRoom.h"
@implementation GenericRoom
@synthesize mySprite, myType, test;

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

    }
    return self;
}

-(id)initWithType: (enum Rooms) roomType {
    if (self = [super init]) {
        myType = roomType;

    }
    return self;
}

-(id)initWithSprite: (NSString *)file {

    if (self = [super init]) {
        mySprite = [CCSprite spriteWithFile:file];

        [self addChild: mySprite];
    }

    return self;
}
@end

RoomManager.h

#import <Foundation/Foundation.h>
#import "cocos2d.h"
#import "GenericRoom.h"
#import "RoomTavern.h"
#import "RoomEmpty.h"

enum Sides {
    LEFT, RIGHT, UP, DOWN
}theSides;

@interface RoomManager : CCLayer {
    CGSize size;
    NSMutableArray *myRooms;
}

- (void) CreateRoom: (enum Rooms)roomType;


@end

RoomManager.m

@implementation RoomManager

-(id)init {

    if (self = [super init]) {
        size = [[CCDirector sharedDirector] winSize];
        myRooms = [[NSMutableArray alloc] initWithCapacity:15];

        for (int i = 0; i < 15; i++) {
            GenericRoom *tmpRoom = [[GenericRoom alloc] initWithType:TAVERN];
            tmpRoom.test = 10;
            [myRooms insertObject:tmpRoom atIndex:i];
        }

        [self CreateRoom:TAVERN];
    }

    return self;
}

- (void) CreateRoom: (enum Rooms)roomType {
    switch (roomType) {
        case TAVERN:
        {
            //Create the Tavern Main Room
            RoomTavern *tmpRoom = [[RoomTavern alloc] initWithSprite:@"room-hd.png"];
            tmpRoom.mySprite.position = ccp(size.width/2,size.height/2);

            [self addChild:tmpRoom];

            [myRooms removeObjectAtIndex:8];
            [myRooms insertObject:tmpRoom atIndex:8];

            if ([self CheckAdjacentRooms:8 andSide:LEFT]) {
                RoomEmpty *tmpEmptyRoom = [[RoomEmpty alloc] initWithSprite:@"roomToBuild-hd.png"];
                tmpEmptyRoom.mySprite.position = ccp(tmpRoom.mySprite.position.x - tmpRoom.mySprite.contentSize.width, tmpRoom.mySprite.position.y);

                [self addChild:tmpEmptyRoom];

                [myRooms insertObject:tmpEmptyRoom atIndex:7];
            }

            break;
        }

        default:
            break;
    }
}

- (BOOL) CheckAdjacentRooms: (int)currentIndex andSide:(enum Sides)side {
    int leftRightSide = 0;
    if(side == LEFT)
        leftRightSide = -1;
    else if (side == RIGHT) 
        leftRightSide = 1;

    GenericRoom *roomTmp  = (GenericRoom *)[myRooms objectAtIndex:currentIndex + side];

    if (roomTmp.myType == EMPTY) {
        return YES;
    }
    else
        return NO;
}

@end
4

3 に答える 3

0

上記のコードが実際のプロジェクトでの表示方法である場合、問題はmyRoomsオブジェクトを再宣言していることです。この行を書くとき:

NSMutableArray *myRooms = [[NSMutableArray alloc] initWithCapacity:15];

myRooms現在のスコープ(メソッド、ブロックなど)を終了すると失われる、という名前の新しいローカルスコープのオブジェクトを作成しています。

これを修正するにはNSMutableArray *、行頭の を削除するだけで、新しく割り当てられた配列がプロパティに割り当てられます。そのようです:

myRooms = [[NSMutableArray alloc] initWithCapacity:15];
于 2012-11-09T17:20:42.290 に答える
0

イニシャライザにはいくつかの欠陥があるようで、問題が発生する可能性があります。

// NOTE: `Rooms` instead of `enum Rooms`
- (id)initWithType:(Rooms)roomType 
{ 
   if (self = [super init])  
   {
      // NOTE: accessor is used, otherwise the value is cleared when out of scope
      self.myType = roomType; 
   }
   return self;
}
于 2012-11-09T18:12:18.543 に答える
0

@Dan Fの回答を強化する。これを読む ...

http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/objectivec/Chapters/ocObjectsClasses.html#//apple_ref/doc/uid/TP30001163-CH11-SW7

nil...メッセージとは何ですか。ローカルで宣言された変数は、プロパティ (= インスタンス変数)myRoomsを隠します。myRoomsつまり、myRoomsですnil。そして、何が起こる...

GenericRoom *room = (GenericRoom*)[myRooms objectAtIndex: currentIndex + side];

nilメッセージング ルールにより、が を[myRooms objectAtIndex:...]返すためnilroomは に設定されnilます。

if (room.myType == EMPTY) {
    return YES;
}

そしてオブジェクトにroom.myTypeメッセージmyTypeを送りますroomroomつまりnil、戻り値は0- 列挙型には整数のスカラー値が含まれます - これが戻り値の理由です0EMPTYそして、それがあなたの enum = has value の最初の要素であると仮定します0。そして0== 0=> は、インスタンス変数がYESであっても戻ります。myRoomsnil

于 2012-11-09T17:35:31.910 に答える