Loop Objective-C #import

Ho il codice seguente:

#import  #import "ServerRequest.h" // works even though this line is included #import "ServerResponseRecord.h" @protocol ServerRequestDelegate -(void)request:(id)request gotResponseRecord:(ServerResponseRecord*)response; -(void)request:(id)request gotError:(NSError*)error; @end 

Compila e funziona bene. Tuttavia, se sostituisco le dichiarazioni del metodo con:

 -(void)request:(ServerRequest*)request gotResponseRecord:(ServerResponseRecord*)response; -(void)request:(ServerRequest*)request gotError:(NSError*)error; 

Ottengo l’errore di syntax imprevisto “error: expected ‘)’ prima di ‘ServerRequest'”. L’unica ragione per cui posso pensare che questo potrebbe essere un problema è che ServerRequestDelegate.h e ServerRequest.h # si importano a vicenda. Tuttavia, non capisco perché il codice funzioni con la riga #import con la richiesta (id). Inoltre, non capisco perché si tratta di un errore di syntax.

Qualcuno può fornire una buona spiegazione?

Hai già accennato alla spiegazione: un ciclo #import.

La prima cosa che farei è rimuovere il #include e aggiungere la seguente riga sopra la definizione di @protocol :

 @class ServerRequest; 

Questa è una dichiarazione forward class e può aiutare a interrompere il ciclo di importazione. Dai un’occhiata a questa domanda SO per maggiori dettagli. Apple ha anche una breve spiegazione in questa guida .

Fondamentalmente, #import un file fa sì che il compilatore porti l’intero testo di quel file nel file in questione, e sebbene #import sia “più intelligente” di #include , ciò non significa che sei immune da errori di importazione. La dichiarazione @class è un modo per dire al compilatore che esiste una class senza importare l’intestazione. È opportuno utilizzarlo quando è necessario conoscere solo il nome della class, ma non preoccuparsi dei metodi che fornisce. In generale, vuoi utilizzare @class nel file .h e #import nel file .m, in cui stai effettivamente interagendo con la class.

#import “loop” non sono un problema. #importare è lo stesso di #include tranne per il fatto che tiene traccia dei file e si assicura che il preprocessore li legga solo per la prima volta.

Di solito quando ottieni un errore del genere è dovuto a un problema nel file incluso. Quindi l’errore è probabilmente in ServerResponseRecord.h, pensavo che probabilmente è stato fatto intervenire usando effettivamente l’object da esso dichiarato. Senza vedere le intestazioni complete non è ansible dire esattamente cosa sta succedendo.