这是循环引用吗?
我有一个继承自 CCSprite
的类,名为 GameObject
。我还有一个名为 ActionDispatcher
的单例,它继承自 NSObject
。
ActionDispatcher sharedActionDispatcher
的工作是在请求时返回一个 CCActionInterval
,而执行此操作的方法需要引用请求对象,该对象的类型为 GameObject(或其子类)。但要让
GameObject
能够请求此操作,它需要引用 ActionDispatcher
。所以我在 ActionDispatcher
标头中有一个 #import "GameObject.h"
,在 GameObject< 中有一个
#import "ActionDispatcher"
/代码> 标头。
我收到错误:在引用 GameObject
的 ActionManager
方法中,Expected ')' before '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
I have a class that inherits from CCSprite
called GameObject
. I also have a singleton called ActionDispatcher
that inherits from NSObject
.
The ActionDispatcher sharedActionDispatcher's
job is to return a CCActionInterval
when asked, and the method that does this requires a reference to the asking object, which is of type GameObject
(or a subclass thereof). But for the GameObject
to be able to ask for this, it needs to refer to ActionDispatcher
. So I have a #import "GameObject.h"
in the ActionDispatcher
header and a #import "ActionDispatcher"
in the GameObject
header.
I get an error: Expected ')' before 'GameObject'
in the ActionManager
method that takes a reference to a GameObject
.
EDIT: added comments to show where I fixed this per the accepted answer below.
//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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
只需在 ActionDispatcher.h 中的
@interface
上方添加一个@class
指令即可。这是在实现中导入的类的前向声明。@class GameObject;
Just add a
@class
directive in ActionDispatcher.h above the@interface
. This is a forward declaration of a class that is imported in the implementation.@class GameObject;
可能的。尝试
在 ActionManager.m 中导入后插入前向声明?这应该会打破这个循环。
Possible. Try inserting
forward declaration after the import in ActionManager.m? This should break the cycle.
这不是问题。 #import 指令自动处理已包含文件的包含。 讨论在这里。
要检查它是否注释掉所有其他导入,请从 NSObject 子类化您的 GameObject,它将编译而不会出现错误。
该错误表明您包含的文件之一存在问题。有时,它可能是头文件中 @end 关键字后面的错误符号,这会使编译器在错误的位置发出错误消息。
This is not the problem. #import directive automatically handles inclusion of already included files. Discussion is here.
To check it comment out all other imports, subclass your GameObject from NSObject and it will compile without errors.
The error tells you there is something wrong in one of the files you include. Sometimes it can be a wrong symbol in a header file after the @end keyword, which makes the compiler complain in the wrong place.