簡體   English   中英

從其他類檢索變量不起作用

[英]Retrieving variable from other class NOT working

如果我這樣做,是否可以從另一個類中獲取變量:

---------------------------- 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 ,以便另一個類現在為win變量分配NO或者if語句中的win分配不是全局處理的嗎?

如果我在init方法中分配了變量NO並在函數中對其進行了更改,則它將僅采用init方法中已分配的值...為什么是這樣?

如果我在init方法中分配了變量NO並在函數中對其進行了更改,則它將僅采用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類變成單例。

您將要考慮使用協議。 這樣,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

這是使用@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,因此除非您希望將其默認設置為True,否則實際上不需要在init()中設置它。

無論如何,現在在類HelloWorldLayer中將實例變量設置為_win。 每當您要設置它時,始終將其稱為self.win。 這是使用屬性以確保您不會遇到內存泄漏的安全習慣,因為在處理指針時,生成的訪問器將為您釋放並保留。 如果直接設置實例變量,則必須記住先釋放它。

希望這可以幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM