Доступ к переменной экземпляра класса (NSMutable Array) из другого класса - PullRequest
1 голос
/ 21 октября 2010

новичок в Obj C и программировании в целом - многому научился на этом сайте и очень ценю вклад каждого.

Мой сценарий следующий (программирование игры для 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;
}

Файл заголовка 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, который является иваром контроллера представления.

Я попытался вызвать метод класса контроллера представления, чтобы сделать это - но я не могу получить доступ к иварам контроллера представления (потому что это метод класса).Я не знаю, как связаться с классом контроллера представления, чтобы сказать ему, чтобы удалить взорванный объект.

@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

Ваша помощь очень ценится.Заранее спасибо!

Ответы [ 4 ]

2 голосов
/ 21 октября 2010

Я рекомендую вам создать объект "Environment", который будет обрабатывать всю игровую логику.

Вишневая бомба не должна справляться со своим взрывом.Вишневая бомба может хранить много информации (размер взрыва, тип взрыва и т. Д.), Но влияние cherryBomb на другие «вещи» (персонажи, бомбы и т. Д.) Не должно рассчитываться самой 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

1 голос
/ 21 октября 2010

Есть несколько способов сделать это, и вы можете подумать о точном разделении труда здесь, с точки зрения контроллеров и моделей.Вещи могут стать довольно спагетизированными, если у вас слишком много звонков туда и обратно.

Однако, не вдаваясь во все это, основная вещь, которую вам нужно сделать, чтобы один объект получил доступ к другому объекту, это дать первыйссылка на второй.

В этом случае вы фактически создаете 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];

Обратите внимание, что вы абсолютно не должны обращаться к массиву контроллера напрямуюэто деталь реализации, о которой ваша бомба не должна знать.В простых случаях вы можете быть немного неаккуратными в своих управляющих структурах, но никогда не вяжут с вашей инкапсуляцией.

0 голосов
/ 21 октября 2010

Я думаю, что это хорошее применение наблюдения значения ключа .Вам нужно свойство вишневой бомбы, которое представляет ее состояние, например

@property (assign) BOOL isExploded;

Любой объект, который интересуется, взорвалась ли вишневая бомба, регистрируется для КВО в свойстве isExploded.Например, контроллер представления может сделать:

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

и в -observeValueForKeyPath:ofObject:change:context: для контроллера представления удалить вишневую бомбу из массива.

Ваш метод детонирования делает следующее, как и всеиначе это в настоящее время делает:

[self setExploded: YES];
0 голосов
/ 21 октября 2010

Прочтите схему проектирования MVC.Если вы найдете ивары, которыми вам нужно поделиться среди представлений, они, вероятно, должны перейти в объект модели более высокого уровня (M of MVC), вместо того, чтобы какой-то вид достиг пика в иварах другого представления.Затем указатель на этот объект Model может быть передан всем объектам представления, которым необходим доступ к нему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...