从另一个类访问类的实例变量(NSMutable Array)

从另一个类访问类的实例变量(NSMutable Array)

问题描述:

新的Obj C和一般的编程 - 从这个网站学到很多东西,非常感谢大家的贡献。从另一个类访问类的实例变量(NSMutable Array)

我的情况如下(编程的iPhone游戏,这解释了有趣的名字)

在我的主要gameLoop(这是在我的视图控制器)如果一定条件满足我制造一个敌人 - 樱桃炸弹

if (bounceCounterGlobal % 2 == 0 && bounceCounterGlobal > 1 && cherryBombSwitch == 0){ 
    [self addCherryBomb]; 
} 

的addCherryBomb方法如下:

-(void) addCherryBomb{ 
    CherryBomb *myCherryBomb = [[CherryBomb alloc] init]; 
    [cherryBombArray insertObject:myCherryBomb atIndex:0]; 
    [myCherryBomb release]; 
    [[cherryBombArray objectAtIndex:0] initializeCherryBomb]; 
    [self.view addSubview:[[cherryBombArray objectAtIndex:0] cherryBombView]]; 
    cherryBombSwitch = 1; 
} 

的樱桃炸弹头文件短:

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

    @interface CherryBomb : NSObject { 

     UIImageView *cherryBombView; 
     NSTimer *cherryBombDetonateTimer; 
     NSTimer *cherryBombMoveTimer; 
    } 

    @property (nonatomic, retain) UIView *cherryBombView; 

    -(void) initializeCherryBomb; 
    -(void) detonateCherryBomb; 
    -(void) moveCherryBomb; 

    @end 

我想要做的是当樱桃炸弹引爆(这是在樱桃炸弹对象内部确定的)时,我希望该对象从樱桃炸弹阵列中移除,而樱桃炸弹阵列是视图控制器的一个ivar。我试图调用一个视图控制器类方法来做到这一点 - 但我无法访问视图控制器的ivars(因为它是一个类方法)。我不知道如何通知视图控制器类来告诉它去除分解对象。

@implementation CherryBomb 
... 
-(void) detonateCherryBomb{ 
    NSLog(@"KABOOM!"); 
    cherryBombDetonateTimer = nil; 
    [cherryBombMoveTimer invalidate]; 
    [cherryBombView removeFromSuperview]; 
    //I would like to remove this object from the view controller's cherryBombArray 
} 
@end 

您的帮助是非常感谢。先谢谢你!

我建议你创建一些能处理所有游戏逻辑的“环境”对象。

樱桃炸弹不应该对付它的爆炸。樱桃炸弹可以存储许多信息(爆炸的大小,爆炸的类型等),但樱桃炸弹对其他“物体”(角色,炸弹等)的影响不应该由樱桃炸弹本身来计算。

我不是很习惯游戏编程,但是这个架构/设计方面很常见:每个对象/类都有其职责。

樱桃炸弹代表炸弹,不再是(也不是“图形”方面)。

环境代表当前时刻的“世界”,并模拟世界各元素之间的行为/相互作用。

有很多说要设计一个游戏的最佳途径......

反正给你的问题的答案,你仍然可以使用“事件”。炸弹可以向你的控制器发送一条消息告诉他:“我爆炸了,把我移开”。

在炸弹:

[[NSNotificationCenter defaultCenter] postNotificationName:@"kaBOOM" 
                object:self]; 

在控制器:

[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(methodToCallWhenKaBOOM) 
              name:@"kaBOOM" 
              object:nil]; 

而且

- (void)methodToCallWhenKaBOOM:(NSNotification *)note 
{ 
    // do stuffs 
} 

http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/Reference/Reference.html

有许多方法可以做到日是的,你可能想要从控制器和模型的角度思考这里的确切分工。如果你有太多的来回呼叫,事情可能会变得很苗条。

但是,没有深入了解所有这些,为了让一个对象访问另一个对象,你需要做的基本事情是给第一个对象引用第二个对象。

在这种情况下,您实际上在视图控制器中创建了CherryBomb,因此在此处传递参考很容易。给你的CherryBomb类另一个伊娃这样的:

SimpleGameViewController* cherryBombViewController; 

修改CherryBomb,以使这些init方法或您的initializeCherryBomb一个(这也许应该只是一个单一的方法,顺便说一句)采取这样的指针,并将其分配给伊娃:

- (void) initializeCherryBomb:(SimpleGameViewController*)vc 
{ 
    // ... whatever other stuff you do in here, plus something like: 
    cherryBombViewController = vc; 
} 

当你调用该方法,通过它selfvc参数。再后来,当你的炸弹引爆它可以调用一些你在控制器上添加方法来去掉自己:

[cherryBombViewController handleDetonationOfCherryBomb:self]; 

请注意,您绝对不应该直接存取控制器的阵列 - 这是一个实现细节你的炸弹应该不知道。在简单的情况下,您可以避免在控制结构中存在一些瑕疵,但是永远不会有螺丝与您的封装。

阅读MVC设计模式。如果你发现你需要在视图之间共享的ivars,他们可能应该进入更高层的Model对象(MVC的M),而不是让某些视图到达其他视图的ivars。然后可以将指向此Model对象的指针传递给需要访问它的所有视图对象。

我觉得这是一个很好的应用key value observing。你需要代表其状态的樱桃炸弹属性,例如

@property (assign) BOOL isExploded; 

的任何对象,它是感兴趣的樱桃炸弹是否爆裂寄存器本身志愿的isExploded财产。例如,视图控制器可能会做:

[cherryBomb addObserver: self 
      forKeyPath: @"isExploded" 
       options: .... 
       context: ....]; 

-observeValueForKeyPath:ofObject:change:context:为视图控制器从数组中删除该樱桃炸弹。

你引爆方法执行以下操作以及其他一切它目前正在做:

[self setExploded: YES];