Problème de référence circulaire possible
-
06-07-2019 - |
Question
Je ne suis pas idiot, mais les fichiers d'en-tête me donnent parfois l'impression d'être comme tel. J'ai ce qui est probablement une configuration trop compliquée qui comporte une erreur que je ne peux pas résoudre. Ici, c’est à peu près aussi simple que possible.
- J'ai une classe de contrôleurs contenant une classe de modèles.
- J'ai une classe Scene pour capturer des actions et communiquer avec le contrôleur.
- J'ai une classe Layer qui parle avec la classe Model pour générer l'état du modèle.
- La classe Scene contient la classe Layer uniquement pour la sortie.
- Les scènes doivent contenir des calques déterminés par le framework Cocos2D.
- Les classes de scène spécifiques dérivent d'une classe RootScene qui contient la référence à la classe Controller.
- Les classes de couches spécifiques dérivent d'une classe RootLayer contenant la référence à la classe Model.
- Le contrôleur est responsable de la création des scènes et les scènes sont responsables de la création des couches.
Le problème survient lors de la création d'un calque et du passage du modèle du contrôleur au modèle du calque (dans AScene.m
). Je reçois la "demande de membre 'modèle' dans quelque chose qui ne soit pas une structure ou un syndicat". Le casting ne fonctionne pas et je ne sais pas comment permettre à ces classes de se parler. Je pense qu'une partie du problème pourrait être que la classe Controller contient la classe Model.
Controller.h
#import <Foundation/Foundation.h>
@class Model;
@class AScene;
@interface Controller : NSObject {
Model *Model;
}
@property (nonatomic, retain) Model *Model;
-(void)runScene;
Controller.m
#import "Controller.h"
#import "Model.h"
#import "AScene.h"
@implementation Controller
@synthesize Model;
- (void)runScene {
AScene *newScene = [[AScene alloc] init];
newScene.controller = self;
}
RootScene.h
#import "cocos2d.h"
@class Controller;
@interface RootScene : Scene {
Controller *controller;
}
@property (nonatomic, retain) Controller *controller;
@end
RootScene.m
#import "RootScene.h"
#import "Controller.h"
@implementation RootScene
@synthesize controller;
- (id) init {
self = [super init];
if (self != nil) {
//
}
return self;
}
- (void) dealloc {
[controller release];
[super dealloc];
}
@end
AScene.h
#import "RootScene.h"
@class ALayer;
@class Model;
@interface AScene : RootScene {
}
@end
AScene.m
#import "AScene.h"
#import "ALayer.h"
#import "Model.h"
@implementation AScene
- (id) init {
self = [super init];
if (self != nil) {
ALayer *newLayer = [ALayer node];
newLayer.model = controller.Model; // <-- Request for member 'Model' in something not a stucture or union
[self addChild:statusScreenLayer];
}
return self;
}
- (void) dealloc {
[super dealloc];
}
@end
RootLayer.h
#import "cocos2d.h"
@class Model;
@interface RootLayer : Layer {
Model *model;
}
@property (nonatomic, retain) Model *model;
@end
RootLayer.m
#import "RootLayer.h"
#import "Model.h"
@implementation RootLayer
@synthesize model;
- (id) init {
self = [super init];
if (self != nil) {
//
}
return self;
}
- (void) dealloc {
[model release];
[super dealloc];
}
@end
ALayer.h
#import "RootLayer.h"
@interface ALayer : RootLayer {
}
-(void) draw;
@end
ALayer.m
#import "ALayer.h"
@implementation ALayer
-(void) draw {
// draw based on state of the model
}
@end
La solution
Votre implémentation de AScene
ne #import
pas l'en-tête de Controller
.
Modifier: Solution explicite.
Dans AScene.m, ajoutez:
#import "Controller.h"
Autres conseils
Nikolai semble avoir raison. Au-delà de cela, les meilleures pratiques indiqueraient que les propriétés (telles que ivars) NE doivent PAS commencer par une lettre majuscule. Vous demandez juste pour le mal. Utilisez-les plutôt:
Controller.h
@interface Controller : NSObject {
Model *model;
}
@property (nonatomic, retain) Model *model;
Controller.m
@synthesize model;