我是使用Objective-C和Stackoverflow进行编程的新手,我需要一些帮助。
我正在尝试从NSMutableArray获取一个对象并检查其内部属性之一。我认为最好的方法是做以下演员:
GenericRoom *room = (GenericRoom*)[myRooms objectAtIndex: currentIndex + side];
if (room.myType == EMPTY) {
return YES;
}
问题在于,当我创建GenericRoom类型的类时,构造函数已经将myType定义为EMPTY。当我在NSMutrableArray中插入实例时,我用这种方式改为myType TAVERN:
NSMutableArray *myRooms = [[NSMutableArray alloc] initWithCapacity:15];
for (int i = 0: i <15: i + +) {
GenericRoom tmpRoom * = [[GenericRoom alloc] initWithType: TAVERN];
myRooms insertObject: tmpRoom atIndex i];
}
但是当我在那里引用它时,它只是创建一个对象GenericRoom的新实例,而不是复制NSMutableArray中的对象,使其结果始终为YES,我的失败vereficação。
有没有更好的方法来解决这个问题? 谢谢大家。
编辑:完整的代码
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
答案 0 :(得分:0)
如果上面的代码是它在实际项目中的显示方式,那么问题是您要重新声明myRooms
对象。当你写这一行时:
NSMutableArray *myRooms = [[NSMutableArray alloc] initWithCapacity:15];
您正在创建一个名为myRooms
的新本地范围对象,当您退出当前范围(方法,块等)时会丢失该对象
解决此问题需要做的只是删除行开头的NSMutableArray *
,然后将新分配的数组分配给您的属性。像这样:
myRooms = [[NSMutableArray alloc] initWithCapacity:15];
答案 1 :(得分:0)
提升@Dan F答案。读这个...
...什么是nil
消息。您在本地声明的myRooms
变量隐藏了您的myRooms
属性(=实例变量)。换句话说,myRooms
是nil
。会发生什么......
GenericRoom *room = (GenericRoom*)[myRooms objectAtIndex: currentIndex + side];
由于nil
消息传递规则,[myRooms objectAtIndex:...]
会返回nil
,因此您的room
设置为nil
。
if (room.myType == EMPTY) {
return YES;
}
room.myType
向myType
对象发送消息room
。因为room
是nil
,返回值是0
- 枚举确实包含整数标量值 - 这就是它返回0
的原因。我假设EMPTY
是你的枚举中的第一个元素=有值0
。并0
== 0
=&gt;即使您的YES
实例变量为myRooms
,也会返回nil
。
答案 2 :(得分: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;
}