Impossible de trouver la déclaration de protocole

J’ai deux view controllers A et B , et ils ont tous deux comme delegates.

Lorsque je n’ai rien fait sauf définir les protocoles au début des fichiers d’en-tête et #import le fichier d’en-tête de l’autre, j’ai eu deux erreurs dans le sens de –

ne peut pas trouver la déclaration de protocole pour “BDelegate”, qui apparaissait dans Ah (où j’ai écrit) ne peut pas trouver la déclaration de protocole pour “ADelegate”, qui apparaissait dans Bh (où j’ai écrit)

En regardant en ligne, les gens avaient écrit plus tôt que l’inclusion circulaire de fichiers d’en-tête pouvait entraîner des problèmes. Ils ont recommandé d’utiliser à la place #include ou la déclaration @class comme –

 @class A 

au lieu de

 #import Ah 

dans #import Bh

J’ai essayé presque toutes les combinaisons de ces importations, et @classes , et #include mais @classes n’arrive toujours pas à éliminer les avertissements. En outre, les solutions en ligne recommandent de déplacer le fichier #import vers les fichiers .m , mais cela n’aide pas non plus. La raison en est que les solutions en ligne sont un peu floues – si vous pouviez les décomposer, ce serait génial.

Des suggestions sur ce qui peut être fait pour résoudre ce problème?


– BigViewController.h –

 #import "BaseViewController.h" #include "BaseViewController.h" @class BigViewController; @protocol BigViewControllerDelegate -(void) BigViewController:(BigViewController *) bigView; @end @interface BigViewController : UIViewController  { //delegate id  delegate; ivars... } @properties... @end -------------------------------------------------- 

– BaseViewController.h –

 # #import "BigViewController.h" #include "BigViewController.h" @class BigViewController; @protocol BaseViewControllerDelegate - (void) setParametersWithItemChosen:(Item *) item; @end @interface BaseViewController : UIViewController  { ivars... //delegate id  delegate; } @properties... @end 

Permettez-moi de réduire l’échantillon encore plus loin et d’étiqueter les lignes:

VC1.h

 #import "VC2.h" // A @class VC1; @protocol VC1Delegate // B @end @interface VC1 : UIViewController  // C @end 

VC2.h

 #import "VC1.h" // D @class VC2; @protocol VC2Delegate // E @end @interface VC2 : UIViewController  // F @end 

Considérez ce qui se passe quand quelque chose #imports VC1.h: il atteint la ligne A, puis l’importation est traitée. La ligne D ne fait rien car VC1.h était déjà importé. Ensuite, la ligne E est traitée. Ensuite, la ligne F, et nous obtenons une erreur car nous ne sums pas encore arrivés à la ligne B, donc le protocole n’est pas déclaré!

Considérez alors ce qui se passe quand quelque chose #importe VC2.h: il atteint la ligne D, puis l’importation est traitée. La ligne A ne fait rien car VC2.h était déjà importé. Ensuite, la ligne B est traitée. Ensuite, la ligne C, et nous obtenons une erreur car nous ne sums pas encore arrivés à la ligne E, donc le protocole n’est pas déclaré!

La première étape consiste à reconsidérer la question de savoir si ces deux classes doivent vraiment être mutuellement déléguées. Si vous pouvez briser le cycle, ce serait probablement la voie à suivre. Sinon, vous devrez restructurer vos en-têtes. Le moyen le plus simple est probablement de mettre les delegates dans leurs propres en-têtes:

VC1Delegate.h

 @class VC1; @protocol VC1Delegate // B @end 

VC1.h

 #import "VC1Delegate.h" #import "VC2Delegate.h" @interface VC1 : UIViewController  // C @end 

VC2Delegate.h

 @class VC2; @protocol VC2Delegate // E @end 

VC2.h

 #import "VC1Delegate.h" #import "VC2Delegate.h" @interface VC2 : UIViewController  // F @end 

Si vous suivez les importations maintenant, vous verrez que les protocoles appropriés seront toujours déclarés avant que les lignes @interface ne les utilisent.

Écrivez le code de déclaration de protocole au-dessus des lignes #import, par exemple

@ protocole —–

@fin

importer —-

@interface classname —

J’ai eu presque le même problème, et je l’ai corrigé grâce à la réponse ci-dessus, mais d’une manière légèrement différente.

tout ce que j’ai fait a été de mettre la ligne #import après la déclaration du protocole dans le fichier d’en-tête. J’espère que je peux aider. et si quelqu’un sait que c’est une mauvaise programmation pour une raison quelconque, veuillez me le faire savoir

J’ai trouvé une autre solution à ce problème car je n’aimais pas vraiment l’idée d’avoir juste quelques #imports entre la classe et la déclaration de protocole.

Fondamentalement, il vous suffit de déplacer du fichier de classe .h vers l’extension de classe dans le fichier .m

Donc, dans votre fichier .m, vous ajoutez

 @interface YourClassName ()  @end 

Je ne sais pas si c’est vraiment une bonne pratique, mais cela semble être une solution plus propre pour éviter les cycles d’importation.

Essayez de placer le ou dans le fichier d’implémentation plutôt que dans le fichier d’en-tête. Ça va marcher.

J’ai suivi le correctif du déplacement du protocole avant l’importation et le problème a été résolu … L’importation incluait le délégué, ce qui posait problème.

Mais alors j’ai pensé, pourquoi importais-je le délégué de toute façon? Je ne faisais pas référence à ses propriétés et je n’appelais aucune de ses méthodes directement (c’est ce que le protocole déclarait).

J’ai essayé de commenter l’importation du délégué et j’ai vu où l’erreur était apparue et j’ai constaté que ce que j’importais lorsque j’importais le délégué était en fait une déclaration que le délégué importait, c’est-à-dire que j’importais A importait B, ce que j’utilisais en fait était B. J’ai donc laissé l’importation de A commentée et ajouté une importation pour B. Ensuite, je pourrais remettre l’ordre du protocole d’importation tel qu’il était.