probleme infernal en objective C

jannold2

Membre confirmé
11 Avril 2007
55
0
39
bonjour, je suis en train de me faire une petite appli en objective C/cocoa et j'ai un probleme : on dirait qu'un pointeur disparait...

je m'explique :
j'ai 2 classes a et b, et dans a il y a une référence sur b
dans b il y a une méthode "afficher 'bonjour' à l'écran"

à l'initialisation de a, je donne le pointeur sur b. il peut demander à b d'afficher 'bonjour'
mais plus tard... il ne peut plus

j'ai réduit mon code au strict minimum, soit 30 lignes. et je ne fais pas d'affectations ni rien. le dealloc() ne s'exécute pas non plus
bref ca me rend fou. mais je suis inexpérimenté, donc si vous avez déja eu le meme probleme... merci de m'aider !!

En espérant avoir aiguisé votre curiosité...

Thomas

(P.S : a propos, si on veut avoir un classe "jeu", "controleur", "myview", doit on tout iniialiser depuis le controleur ? je ne vois pas vraiment où est la fonction main, ou alors s'il y a un endroit un peu plus global pour créer des instances. le controleur c'est pratique à cause de IB qui le fait)

code :
ca c'est la classe 'b', et recoitclic affiche qqchose. normalement.

@class MyView;

@interface Partie : NSObject {
MyView* dessin;
}

-(Partie*) init:(MyView*) window;
-(void) recoitclic;
-(void) dealloc;
@end


#import "Partie.h"
#import "MyView.h"

@implementation Partie
-(Partie*) init:(MyView*) window {
dessin = window;
//[MyView init];

return self;
}
-(void) recoitclic {
NSLog(@"clic\n");
}

-(void) dealloc {
NSLog(@"dealoc\n");
[super dealloc];
}
@end


ca c'est la classe 'a' :
@class Partie;

@interface MyView : NSOpenGLView {
Partie* master;
}
- (MyView*) init;
- (void) setMaster:(Partie*) parti;
- (void) drawRect: (NSRect) bounds;
- (void) mouseUp:(NSEvent *)theEvent;
@end

#import "MyView.h"
#include <OpenGL/gl.h>
#import "Partie.h"

@implementation MyView

-(void) setMaster:(Partie*) parti {
master = parti;
[master recoitclic];
}

- (MyView*) init{
return self;
}

-(void) drawRect: (NSRect) bounds {
}

-(void)mouseUp:(NSEvent *)theEvent {
NSLog(@"coucou\n");
[master recoitclic];
}

@end


et le controleur :

@class Partie, MyView;

@interface Controleur : NSObject {
IBOutlet NSButton* bouton_start;
IBOutlet MyView* window;
Partie* game;
}
-(IBAction)nouvellepartie:(id) sender;
@end

#import "Controleur.h"
#import "Partie.h"
#import "MyView.h"

@implementation Controleur

-(IBAction)nouvellepartie:(id) sender {
[bouton_start setHidden:YES];
window = [[MyView alloc] init];
game = [[Partie alloc] init:window];
[window setMaster:game];
[game retain]; // à mettre ? mis ou pas, ca ne marche pas
}

@end


tout est a chaque fois mis dans 2 fichiers .h et .m
 
Tout d'abord, ce qui me saute aux yeux, c'est la façon dont tu écris tes méthodes d'init. Voici la bonne:

Bloc de code:
// Une méthode d'init standard 
- (id) init
{
	if(self = [super init])
	{
		// Initialiser ici les variables d'instances
		
	}
	
	return self;
}

C'est une forme idiomatique, tu comprendras par la suite pourquoi elle s'écrit ainsi, mais pour l'instant, calque tes méthodes d'init dessus.



Bon, désolé je vais m'arrêter là, parce que je pense qu'il te manque trop d'éléments, à commencer par une bonne doc. Nous conseillons toujours ici l'excellent Cocoa par la pratique. Ça vaut vraiment le coup. L'auteur vient de sortir une troisième version de son livre, qui n'est donc dispo qu'en anglais, mais il serait plus intéressant d'acheter celui-ci pour la suite.

Voilà, désolé de ne pas t'aider d'avantage, mais il y a des limites inhérentes à un forum.
 
Ta classe dérive de NSObject. Quand tu initialises une classe dérivée il faut toujours appeler en premier le constructeur de la classe mère pour profiter de cette dérivation et avoir un objet correctement initialisé, et ce quelque soit le langage objet utilisé.
 
Merci pour les conseils
j'ai changé la méthode init comme il faut, mais... ca ne marche toujours pas !

a priori il n'y a aucune raison pour que ca ne marche plus maintenant, sauf peut etre si dans le controleur il "jette" le game. comment etre sur qu'il ne le fasse pas ?
 
j'ai changé la méthode init comme il faut, mais... ca ne marche toujours pas !
Avec ça on n'est pas très avancé. :rateau:
La seule difficulté de l'Obj-C c'est la gestion de la mémoire. Donc repenche toi la dessus, notamment l'usage de retain et release.

PS : dans tes messages met ton code dans des balises "code" / "/code" pour que cela soit plus lisible.
 
(P.S : a propos, si on veut avoir un classe "jeu", "controleur", "myview", doit on tout iniialiser depuis le controleur ? je ne vois pas vraiment où est la fonction main, ou alors s'il y a un endroit un peu plus global pour créer des instances. le controleur c'est pratique à cause de IB qui le fait)

Dans le groupe Other Sources de ton projet, il y a un fichier main.m:

Bloc de code:
int main(int argc, char *argv[])
{
    return NSApplicationMain(argc, (const char **) argv);
}

Il est là ton programme principal, ensuite NSApplicationMain() crée une instance de NSApplication, qui se démerde pour aller voir dans Info.plist le nom du fichier .nib à ouvrir et t'instancie tout ce qu'il y a dedans. Maintenant, si tu veux instancier des objets:
- soit tu fais ça dans un NSObject que tu as glissé dans le .nib
- soit tu crées un délégué de l'application