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

发布于 2024-09-28 01:34:19 字数 1683 浏览 1 评论 0原文

Obj C 和一般编程新手 - 从这个网站学到了很多东西,非常感谢每个人的贡献。

我的场景如下(编写一个解释有趣名称的 iPhone 游戏)

在我的主 gameLoop(位于我的视图控制器中)中,如果满足特定条件,我会创建一个敌人 - 樱桃炸弹

if (bounceCounterGlobal % 2 == 0 && bounceCounterGlobal > 1 && cherryBombSwitch == 0){
    [self 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;
}

addCherryBomb方法 CherryBomb 头文件很短:

#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

我想做的是当樱桃炸弹爆炸时(这是在cherryBomb 对象内确定的),我希望该对象从cherryBombArray 中删除自身,cherryBombArray 是视图控制器的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

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

new to Obj C and programming in general - learned a lot from this site and really appreciate everyone's contributions.

My scenario is as follows (programming an iPhone game which explains the funny names)

In my main gameLoop (which is in my view controller) if a certain condition is met I create an enemy - the cherry bomb

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

The addCherryBomb method is as follows:

-(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;
}

The CherryBomb header file is short:

#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

What I would like to do is when the cherry bomb detonates (which is determined within the cherryBomb object), I would like the object to remove itself from the cherryBombArray which is an ivar of the view controller.

I tried calling a view controller class method to do this - but I am unable to access ivars of the view controller (because it is a class method). I do not know how to communicate back to the view controller class to tell it to remove the exploded object.

@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

Your help is greatly appreciated. Thank you in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

甜心小果奶 2024-10-05 01:34:19

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

樱桃炸弹不应该处理它的爆炸。 cherryBomb 可以存储许多信息(爆炸的大小、爆炸类型等),但是cherryBomb 对其他“事物”(角色、炸弹等)的影响不应该由ch​​erryBomb 本身计算。

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

cherryBomb 代表一颗炸弹,仅此而已(也不是“图形”方面)。

环境代表当前时刻的“世界”,并对世界元素之间的动作/交互进行建模。

关于设计游戏的最佳方法有很多话要说……

无论如何,为了回答你的问题,你仍然可以使用“事件”。炸弹可以向你的控制器发送一条消息,告诉他:“我爆炸了,把我移走”。

在炸弹中:

[[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

I recommend you to create some "Environment" object that will handle all the gaming logic.

The cherryBomb shouldn't deal with its explosion. The cherryBomb can store many information (size of the explosion, type of explosion, and so on), but the effects of the cherryBomb on the others "things" (characters, bombs, whatever) shouldn't be calculated by the cherryBomb itself.

I'm not very used to game programming, but this aspect of architecture/design is common: each object/class has its responsibilities.

The cherryBomb represents a bomb, no more (and not the "graphic" aspect either).

The Environnement represents a "world" at current instant, and modelizes actions/interactions between the elements of the world.

There is a lot to say about the best way to design a game...

Anyway, to give your question an answer, you can still use "events". The bomb can send a message to your controller telling him: "I've exploded, remove me".

In the bomb:

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

In the controller:

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

And

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

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

葬花如无物 2024-10-05 01:34:19

有多种方法可以做到这一点,您可能需要考虑控制器和模型方面的确切分工。如果你来来回回的电话太多,事情就会变得非常混乱。

然而,在不深入讨论所有这些的情况下,要允许一个对象访问另一个对象,您需要做的基本事情是为第一个对象提供对第二个对象的引用。

在本例中,您实际上是在视图控制器中创建 CherryBomb,因此此时很容易向其传递一个引用。为您的 CherryBomb 类提供另一个 ivar,如下所示:

SimpleGameViewController* cherryBombViewController;

修改 CherryBomb 以便 init 方法或您的 initializeCherryBomb 方法 (这些可能应该只是一个方法,顺便说一句)接受这样一个指针并将其分配给 ivar:

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

当您调用它时,将其作为 vc 参数传递给 self 。然后,当你的炸弹引爆时,它可以调用你在控制器上添加的一些方法来删除自己:

[cherryBombViewController handleDetonationOfCherryBomb:self];

请注意,你绝对不应该直接访问控制器的数组 - 这是你的炸弹应该具有的实现细节不知道。在简单的情况下,您可以在控制结构中稍微草率一点,但永远不要破坏您的封装。

There are a number of ways to do this, and you may want to think about the exact division of labour here, in terms of controllers and models. Things can get pretty spaghettified if you have too much calling back and forth.

However, without getting into all of that, the basic thing you need to do to allow one object to access another object is to give the first a reference to the second.

In this case, you're actually creating the CherryBomb in the view controller, so it's easy to just pass it a reference at that point. Give your CherryBomb class another ivar like this:

SimpleGameViewController* cherryBombViewController;

Modify CherryBomb so that either the init method or your initializeCherryBomb one (these probably should just be a single method, btw) takes such a pointer and assigns it to the ivar:

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

When you call this, pass it self as the vc parameter. Then later on, when your bomb detonates it can invoke some method you add on the controller to remove itself:

[cherryBombViewController handleDetonationOfCherryBomb:self];

Note that you absolutely should not access the controller's array directly -- that's an implementation detail your bomb should have no knowledge of. You can get away with being a little sloppy in your control structures in simple cases, but never screw with your encapsulation.

傲影 2024-10-05 01:34:19

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

Read up on the MVC design pattern. If you find ivars which you need to share among views, they should probably go in a higher level Model object (the M of MVC), instead of having some view's peaking into other view's ivars. A pointer to this Model object can then be passed down to all the view objects that need to access it.

浅唱ヾ落雨殇 2024-10-05 01:34:19

我认为这是键值观察的一个很好的应用< /a>.您需要樱桃炸弹的一个属性来表示其状态,例如,

@property (assign) BOOL isExploded;

任何对樱桃炸弹是否爆炸感兴趣的对象都会在 isExploded 属性上为 KVO 注册自身。例如,视图控制器可能会这样做:

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

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

您的 detonate 方法会执行以下操作以及它当前正在执行的所有其他操作:

[self setExploded: YES];

I think this is a good application of key value observing. You need a property of the cherry bomb which represents its state e.g.

@property (assign) BOOL isExploded;

Any object that is interested in whether the cherry bomb has exploded registers itself for KVO on the isExploded property. For example the view controller might do:

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

and in -observeValueForKeyPath:ofObject:change:context: for the view controller remove the cherry bomb from the array.

Your detonate method does the following as well as everything else it is currently doing:

[self setExploded: YES];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文