Это круговая ссылка? - PullRequest
       28

Это круговая ссылка?

0 голосов
/ 14 сентября 2011

У меня есть класс, который наследуется от CCSprite, который называется GameObject.У меня также есть синглтон с именем ActionDispatcher, который наследуется от NSObject.

. Задача ActionDispatcher sharedActionDispatcher's - возвращать CCActionInterval при запросе, а метод, который делает это, требует ссылки на запрашивающий объект., который имеет тип GameObject (или его подкласс).Но для того, чтобы GameObject мог попросить об этом, необходимо обратиться к ActionDispatcher.Таким образом, у меня есть #import "GameObject.h" в заголовке ActionDispatcher и #import "ActionDispatcher" в заголовке GameObject.

Я получаю ошибку: Expected ')' before 'GameObject' в методе ActionManager, который принимает ссылку наa GameObject.

РЕДАКТИРОВАТЬ: добавлены комментарии, чтобы показать, где я исправил это согласно принятому ответу ниже.


//The GameObject interface

#import "cocos2d.h"
#import "ActionDispatcher.h"

@interface GameObject : CCSprite {
    CGPoint homeLocation;
}

@property (readwrite) CGPoint homeLocation;

- (void)updateStateWithDeltaTime:(ccTime)deltaTime 
        andListOfGameObjects:(CCArray*)listOfGameObjects;

@end

//The GameObject implementation

#import "GameObject.h"

@implementation GameObject

@synthesize homeLocation;

- (void)updateStateWithDeltaTime:(ccTime)deltaTime 
        andListOfGameObjects:(CCArray *)listOfGameObjects 
{
    //CCLOG(@"updateStateWithDeltaTime method should be overriden");
}

@end

//The ActionDispatcher interface

#import "cocos2d.h"
#import "CCRotateAround.h"
#import "Constants.h"
#import "GameObject.h" // Answer: Remove this line

// Add this here: @class GameObject;

@interface ActionDispatcher : NSObject {

}

+ (ActionDispatcher *)sharedActionDispatcher;

- (id)actionWithType:(ActionType)actionType 
          withObject:(GameObject *)gameObject 
        withDuration:(float)duration;

@end

//The ActionDispatcher implementation

#import "ActionDispatcher.h"
// and add this here: #import "GameObject.h"

@implementation ActionDispatcher

static ActionDispatcher* _sharedActionDispatcher = nil;

+ (ActionDispatcher*)sharedActionDispatcher 
{
    @synchronized([ActionDispatcher class])                             
    {
        if(!_sharedActionDispatcher)                                    
            [[self alloc] init]; 
        return _sharedActionDispatcher;                                 
    }
    return nil; 
}

+ (id)alloc 
{
    @synchronized ([ActionDispatcher class])                            
    {
        NSAssert(_sharedActionDispatcher == nil,
                 @"Attempted to allocated a second instance of the ActionManager singleton");                                          
        _sharedActionDispatcher = [super alloc];
        return _sharedActionDispatcher;                                 
    }
    return nil;  
}

- (id)actionWithType:(ActionType)actionType 
          withObject:(GameObject *)gameObject 
        withDuration:(float)duration
{
    CGSize screenSize = [[CCDirector sharedDirector] winSize];

    id action = nil;

    switch (actionType) {
        case kActionDiveBomb:
            CCLOG(@"ActionManager returning action of type: dive bomb");
            CGPoint controlPoint1 = ccp(gameObject.position.x, gameObject.position.y*0.5f);
            CGPoint controlPoint2 = ccp(screenSize.width*0.5f, gameObject.position.y*0.5f);
            CGPoint destination = ccp(screenSize.width*0.5f, -gameObject.contentSize.height*0.5f);
            ccBezierConfig diveBombBezier;
            diveBombBezier.controlPoint_1 = controlPoint1;
            diveBombBezier.controlPoint_2 = controlPoint2;
            diveBombBezier.endPosition = destination;
            id diveAction = [CCBezierTo actionWithDuration:duration bezier:diveBombBezier];
            id returnToTopAction = [CCMoveTo actionWithDuration:0.0f position:ccp(gameObject.homeLocation.x, screenSize.height+gameObject.contentSize.height/2)];
            id fallInAction = [CCMoveTo actionWithDuration:duration*0.2 position:gameObject.homeLocation];
            action = [CCSequence actions:diveAction, returnToTopAction, fallInAction, nil];
            break;
        case kActionLoop:
            CCLOG(@"ActionManager returning action of type: loop");
            CGPoint centerPoint = ccp(screenSize.width/2, screenSize.height/2);
            float span = 360.0;
            action = [CCRotateAround actionWithDuration:duration centerPoint:centerPoint spanAngle:span];
            break;
        case kActionSpin:
            CCLOG(@"ActionManager returning action of type: spin");
            action = [CCRotateBy actionWithDuration:duration angle:360.0f];
            break;
        case kActionGoHome:
            CCLOG(@"ActionManager returning action of type: go home");
            action = [CCMoveTo actionWithDuration:0.0f position:[gameObject homeLocation]];
            break;
        case kActionFallIn:
            CCLOG(@"ActionManager returning action of type: fall in");
            action = [CCMoveTo actionWithDuration:duration position:[gameObject homeLocation]];
            break;
        case kActionIdle:
            CCLOG(@"ActionManager returning action of type: idle");
            action = [CCDelayTime actionWithDuration:duration];
            break;
        default:
            CCLOG(@"ActionManager returning action of type: no valid action");
            break;
    }

    return action;
}

@end

Ответы [ 3 ]

2 голосов
/ 14 сентября 2011

Просто добавьте директиву @class в ActionDispatcher.h над @interface. Это предварительное объявление класса, который импортируется в реализацию.

@class GameObject;

0 голосов
/ 14 сентября 2011

Это не проблема.Директива #import автоматически обрабатывает включение уже включенных файлов. Обсуждение здесь .Чтобы проверить это, закомментируйте все другие операции импорта, создайте подкласс GameObject из NSObject, и он будет скомпилирован без ошибок.Ошибка говорит о том, что в одном из включенных вами файлов что-то не так.Иногда это может быть неправильный символ в заголовочном файле после ключевого слова @end, что заставляет компилятор жаловаться не туда.

0 голосов
/ 14 сентября 2011

Возможные. Попробуйте вставить

@class GameObject

пересылка декларации после импорта в ActionManager.m? Это должно разорвать цикл.

...