Cast + Protocole + Datasource

muqaddarmuqaddar Administrateur
Hello,

J'ai une question sur de la syntaxe Objective-C car parfois je ne saisis pas tout...

Lorsque j'écris ce code où reference est une méthode de mon referenceDataSource qui retourne un objet de type (reference*), et _wine une propriété de Reference.h, je me prends un : request for member _wine in something not a structure or union.

[self.referenceDataSource reference]._wine


Pour palier ce problème, je caste sur l'appel de méthode, et déjà  ça m'énerve parce reference renvoie un (Reference*) de toute façon.

(Reference*)[self.referenceDataSource reference]._wine


A ce moment là , je n'ai plus le message.

Mais si je veux accéder à  une propriété de _wine comme _id :

(Reference*)[self.referenceDataSource reference]._wine._id


je me prends le même message sur _id comme quoi ce n'est pas une propriété et tout et tout : request for member _id in something not a structure or union

Cette fois, même en castant à  nouveau, ça ne passe pas :

((Wine*)((Reference*)[self.referenceDataSource reference]._wine))._id


ça me désespère un peu de ne pas pouvoir faire tout simplement :

[self.referenceDataSource reference]._wine._id


qui devrait marcher je pense...

Pour info, ma méthode de protocole appelée est :

- (Reference*)reference<br />{<br />	return self._reference;<br />}


où self._reference est évidemment un objet Reference.

Réponses

  • AliGatorAliGator Membre, Modérateur
    21:19 modifié #2
    Heu j'ai pas tout suivi de pourquoi en effet ça marche pas, mais heu le "return self._reference" est bizarre dans ton dernier bout de code : tu implémentes le getter "reference" en appelant le getter "_reference" (puisque self._reference appelle la le getter généré par @property _reference de ton self)... Donc si ton code est bien celui-là , tu as déjà  un @property _reference apparemment qui existe, pourquoi créer une méthode (Reference*)reference en plus ?
    Ca sent un peu l'embrouille ça...

    Ca t'embêterai de mettre le code de ton .h et .m qui concerne ton problème ? (le .h épuré qui montre la déclaration de ta variable d'instance Reference* + la declaration de ta @property associée, le .m épuré qui montre tes @synthesize et tes implémentations de setter+getter) ? Ca serait plus concret.
  • muqaddarmuqaddar Administrateur
    21:19 modifié #3
    Oui, je sais que je n'arrive pas à  trouver la bonne formule, je te mets le code, tu vas mieux comprendre.

    ReferenceModalViewController.h

    @class Reference;<br /><br />@protocol ReferenceDataSource<br />- (void)loadEmptyReference;<br />- (void)loadFullReference:(NSUInteger)aWineId;<br />- (Reference*)reference;<br />@end<br /><br />@interface ReferenceModalViewController : UIViewController &lt;ReferenceDataSource&gt;<br />{<br />	UINavigationController *navigationController;	<br />	<br />	Reference *_reference;<br />}<br /><br />@property(nonatomic, retain) IBOutlet UINavigationController *navigationController;<br /><br />@property(nonatomic, retain) Reference *_reference;<br /><br />@end
    


    ReferenceModalViewController.m

    @implementation ReferenceModalViewController<br /><br />#pragma mark -<br />#pragma mark accessors<br /><br />@synthesize navigationController;<br />@synthesize _reference;<br /><br />#pragma mark -<br />#pragma mark memory<br /><br />- (void)dealloc <br />{<br />	[navigationController release];	<br />	[_reference release];<br />	[super dealloc];<br />}<br /><br />#pragma mark -<br />#pragma mark protocol<br /><br />- (void)loadEmptyReference<br />{<br />	self._reference = [[Manager sharedManager] newEmptyReference];<br />}<br /><br />- (void)loadFullReference:(NSUInteger)aWineId<br />{<br />	self._reference = [[Manager sharedManager] editFullReference:aWineId];	<br />}<br /><br />- (Reference*)reference<br />{<br />	return self._reference;<br />}<br /><br />@end
    


    Le but est de créer un objet dataSource qui se transmet de contrôleurs en contrôleurs (en objet assign) et qui peut être édité par tous ces contrôleurs.

    Là , j'ai bien une propriété _reference associée à  ce contrôleur mais peut-être y-a-il mieux à  faire ?

    Le code :

    [self.referenceDataSource reference]._wine
    


    est appelé dans les autres contrôleurs où je peux utiliser ce datasource transmis.
  • AliGatorAliGator Membre, Modérateur
    21:19 modifié #4
    Ben oui, puisque ReferenceModalViewController réponds déjà  au protocole <ReferenceDataSource>, par définition il a déjà  une méthode [tt]- (Reference*)reference;[/tt], pourquoi ce n'est pas celle-là  (que tu laisses implémentée automatiquement via @synthesize) au lieu de créer une [tt]@property Reference* _reference;[/tt] en sus ?
  • AliGatorAliGator Membre, Modérateur
    21:19 modifié #5
    Bon je comprend pas, j'ai copié/collé ton code dans un fichier, j'ai rajouté 2-3 dummy-classes pour le faire compiler (classes Wine, Reference et Manager avec le minimum dedans), et j'ai testé le [tt][self.referenceDataSource reference]._wine._id;[/tt], aucun souci.

    Je te joins les deux fichiers en PJ, chez moi dans mon projet de test avec juste cette classe ça ça compile et ça gueule pas quand je teste l'appel, dis moi si ça marche bien aussi chez toi et le cas échéant quelle différence tu vois avec ton code.
  • muqaddarmuqaddar Administrateur
    mars 2010 modifié #6
    Merci à  Ali de m'avoir aiguiller.

    Le problème venait du fait que je me suis mis à  utiliser @class en lieu et place de #import dans mes .h, et que je n'avais pas inclus le #import dans le .m où je fais appel à  mon objet Reference. En conséquence, il ne trouvait pas la propriété _id de _wine.
  • Nebuchad34Nebuchad34 Membre
    21:19 modifié #7
    Aaah Oui, je me faisais avoir avec ça il y a quelques temps. Maintenant que j'ai galéré plusieurs fois je sais faire la différence.  :o
Connectez-vous ou Inscrivez-vous pour répondre.