从其他类中检索变量不起作用

时间:2011-12-16 16:43:38

标签: objective-c cocos2d-iphone

如果我这样做,我可以从另一个类中获取变量:

---------------------------- HelloWorldLayer.h ---------------- ---------------

@interface HelloWorldLayer : CCLayer
{  

...
BOOL win;
...
}

@property (nonatomic,readwrite) BOOL win;

---------------------------- HelloWorldLayer.m ---------------- ---------------

@synthesize win;

-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
  if (...){

  //do something with with variable win ----> IN <---- if statement
  win = YES;
  }
//win is changed only in if statement
}

---------------------------- LevelDone.m ---------------- ---------------

-(void)nextLevel:(id)sender{
    NSLog(@"next level");

    HelloWorldLayer *obj = [[HelloWorldLayer alloc]init];
    if (obj.win==YES){
        NSLog(@"win = YES");
    }else {
        NSLog(@"win = NO");
    }
    win = NO;
    [[CCDirector sharedDirector] popScene];

}

我可以先在此处获取并设置变量win,以便其他类现在具有分配有NO的win变量,或者是否在if语句中分配了未全局处理的win?

如果我在NO方法中分配变量init并在函数中更改它,则只会采用init方法中指定的值...为什么地狱好吗?

3 个答案:

答案 0 :(得分:1)

  

如果我在init方法中指定变量NO并在a中更改它   函数,它只会获取已分配的值   init方法......为什么地狱?

由于您未使用相同的对象,因此您需要创建新对象

HelloWorldLayer *obj = [[HelloWorldLayer alloc]init];
    if (obj.win==YES){
        NSLog(@"win = YES");
    }else {
        NSLog(@"win = NO");
    }

每次运行这行代码时:

HelloWorldLayer *obj = [[HelloWorldLayer alloc]init];

...您创建了一个HelloWorldLayer的新实例。它将运行init方法中的代码,因为您正在向init消息发送它。这就是为什么你在init方法中设置的值将被上面的代码记录下来。

您想要的是访问HelloWorldLayer的现有实例,而不是创建该类的新实例。我相信@Jeremy为您提供了满意的解决方案。另一种方法是将HelloWorldLayer类转换为单例。

答案 1 :(得分:0)

您需要考虑使用协议。这样,LevelDone将被通知HelloWorldLayer是否赢了。特别是如果HelloWorldLayer是一个漫长的进程并且异步运行的话。这是一个粗略的例子:

<强> HelloWorldLayer.h

@protocol HelloWorldLayerDelegate
- (void)helloWorldLayer:(HelloWorldLayer *)layer didWin:(BOOL)win;
@end

@interface HelloWorldLayer : CCLayer
{  

...
BOOL win;
...
}

@property (nonatomic,readwrite) BOOL win;
@property (nonatomic, assign) id <HelloWorldLayerDelegate>delegate;

@end

HelloWorldLayer.h

@implementation HelloWorldLayer 
@synthesize win;
@synthesize delegate;

-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
  if (...){

  //do something with with variable win ----> IN <---- if statement
  win = YES;

     [self.delegate helloWorldLayer:self didWin:win];


  }
//win is changed only in if statement
}

@end

<强> LevelDone.h

@interface LevelDone <HelloWorldLayerDelegate>
    HelloWorldLayer *_hello;
@end

<强> LevelDone.m

@implementation LevelDone

- (void)playLevel {

    _hello = [HelloWorldLayer alloc] init];
    _hello.delegate = self;

    [_hello start];

}

- (void)helloWorldLayer:(HelloWorldLayer *)layer didWin:(BOOL)win {

    //Rather than having a didWin: parameter, maybe you can just check the property of the layer object

    NSLog(@"win = %@", win ? @"YES" : @"NO");


    [[CCDirector sharedDirector] popScene];

}

- (void)dealloc {
  [_hello release];
  [super dealloc];
}

@end

答案 2 :(得分:0)

这是使用@synthesize生成的访问器和直接引用实例变量之间的混淆的一个例子。尝试声明你的财产:

---------------------------- HelloWorldLayer.h ---------------- ---------------

@interface HelloWorldLayer : CCLayer

@property (nonatomic) BOOL win;

---------------------------- HelloWorldLayer.m ---------------- ---------------

@synthesize win=_win;

-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
  if (...){
      self.win = YES;
  }

}

我认为BOOL值始终默认为 False ,所以你真的不需要在init()中设置它,除非你希望它默认为 True

无论如何,现在实例变量在类HelloWorldLayer中设置为_win。无论何时你想设置它总是将它称为self.win。在使用属性时,这是一个安全的习惯,以确保您不会遇到内存泄漏,因为当您处理指针时,生成的访问器将为您释放和保留。如果直接设置实例变量,则必须记住首先释放它。

希望这有帮助!