Objective-C #import loop
У меня есть следующий код:
#import <Foundation/Foundation.h>
#import "ServerRequest.h" // works even though this line is included
#import "ServerResponseRecord.h"
@protocol ServerRequestDelegate<NSObject>
-(void)request:(id)request gotResponseRecord:(ServerResponseRecord*)response;
-(void)request:(id)request gotError:(NSError*)error;
@end
Он компилируется и работает отлично. Однако, если я заменю объявления метода с помощью:
-(void)request:(ServerRequest*)request gotResponseRecord:(ServerResponseRecord*)response;
-(void)request:(ServerRequest*)request gotError:(NSError*)error;
Я получаю непредвиденную синтаксическую ошибку "error: expected" ) до "ServerRequest". Единственная причина, по которой я могу думать, что это может быть проблемой, заключается в том, что ServerRequestDelegate.h и ServerRequest.h #import друг друга. Однако я не понимаю, почему код работает с линией #import с запросом (id). Я также не понимаю, почему это синтаксическая ошибка.
Может ли кто-нибудь дать хорошее объяснение?
Ответы
Ответ 1
Вы уже намекнули на объяснение: цикл #import.
Первое, что я сделал бы, это удалить #include
и добавить следующую строку выше определения @protocol
:
@class ServerRequest;
Это объявление прямого класса и может помочь разбить цикл импорта. Ознакомьтесь с этим вопросом SO для получения более подробной информации. У Apple также есть краткое объяснение в это руководство.
В принципе, #import
'в файле заставляет компилятор передать весь текст этого файла в соответствующий файл, и хотя #import
"умнее", чем #include
, это не означает, невосприимчивы к ошибкам импорта. Объявление @class
- это способ сообщить компилятору, что класс существует без импорта заголовка. Он подходит для использования, когда вам нужно знать только имя класса, но не заботятся о методах, которые он предоставляет. Как правило, вы хотите использовать @class
в файле .h и #import
в файле .m, где вы фактически взаимодействуете с классом.
Ответ 2
#import "loop" не являются проблемой. #import - это то же, что и #include, за исключением того, что он отслеживает файлы и гарантирует, что препроцессор будет читать их только в первый раз.
Обычно, когда вы получаете такую ошибку, это связано с проблемой во включенном файле. Таким образом, ошибка, вероятно, в ServerResponseRecord.h, считается, что она, вероятно, сработала, фактически используя объявленный ею объект. Не видя полных заголовков, невозможно точно сказать, что происходит.