Objective-C # import loop - PullRequest
       22

Objective-C # import loop

12 голосов
/ 03 августа 2009

У меня есть следующий код:

#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: Ожидается») перед «ServerRequest». Единственная причина, по которой я могу думать, что это может быть проблемой, заключается в том, что ServerRequestDelegate.h и ServerRequest.h #import друг друга. Однако я не понимаю, почему код работает со строкой #import с запросом (id). Я также не понимаю, почему это синтаксическая ошибка.

Может ли кто-нибудь дать хорошее объяснение?

Ответы [ 2 ]

26 голосов
/ 03 августа 2009

Вы уже намекали на объяснение: цикл #import.

Первое, что я хотел бы сделать, это удалить #include и добавить следующую строку над определением @protocol:

@class ServerRequest;

Это предварительное объявление класса, которое может помочь разорвать цикл импорта. Проверьте этот вопрос для более подробной информации. У Apple также есть краткое объяснение в этом руководстве .

По сути, #import 'файл заставляет компилятор вносить весь текст этого файла в рассматриваемый файл, и хотя #import "умнее", чем #include, это не означает, что вы' неуязвимы для ошибок импорта. Объявление @class - это способ сообщить компилятору, что класс существует без импорта заголовка. Это целесообразно использовать, когда вам нужно знать только имя класса, но не заботиться о методах, которые он предоставляет. Как правило, вы хотите использовать @class в файле .h и #import в файле .m, где вы фактически взаимодействуете с классом.

0 голосов
/ 03 августа 2009

# импорт "петель" не является проблемой. #import аналогичен #include, за исключением того, что он отслеживает файлы и гарантирует, что препроцессор только читает их в первый раз.

Обычно, когда вы получаете такую ​​ошибку, это связано с проблемой во включенном файле. Таким образом, ошибка, вероятно, в ServerResponseRecord.h, хотя она, вероятно, была отключена путем фактического использования объявленного им объекта. Не видя полных заголовков, невозможно точно сказать, что происходит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...