从另一个类访问类的实例变量(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
}
有许多方法可以做到日是的,你可能想要从控制器和模型的角度思考这里的确切分工。如果你有太多的来回呼叫,事情可能会变得很苗条。
但是,没有深入了解所有这些,为了让一个对象访问另一个对象,你需要做的基本事情是给第一个对象引用第二个对象。
在这种情况下,您实际上在视图控制器中创建了CherryBomb
,因此在此处传递参考很容易。给你的CherryBomb
类另一个伊娃这样的:
SimpleGameViewController* cherryBombViewController;
修改CherryBomb
,以使这些init
方法或您的initializeCherryBomb
一个(这也许应该只是一个单一的方法,顺便说一句)采取这样的指针,并将其分配给伊娃:
- (void) initializeCherryBomb:(SimpleGameViewController*)vc
{
// ... whatever other stuff you do in here, plus something like:
cherryBombViewController = vc;
}
当你调用该方法,通过它self
为vc
参数。再后来,当你的炸弹引爆它可以调用一些你在控制器上添加方法来去掉自己:
[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];