Почему у меня эти ошибки компиляции? Разве #import не защищает снова рекурсивные вызовы?
#import
защищает от неоднократного импорта одного и того же заголовка в один и тот же модуль, независимо от того, включает ли он / импортирует циклически или нет. Он защищает от этого, не позволяя вам сделать это: работает только первый #import
заголовка; последующие #import
s того же заголовка игнорируются.
В циклической ситуации #include
препроцессор будет обходить круг несколько раз, а затем не сможет выполнить сборку, прежде чем вы доберетесь до компиляции. Использование #import
предотвращает заклинивание препроцессора и позволяет преуспевать в успехе, но циклический код #import
в лучшем случае все еще хитрый и обычно не компилируется.
Итак, перейдем к вашей конкретной ситуации.
Для кода, который вы указали в своем вопросе, @class
будет работать с одним или обоими заголовками, и вы действительно должны использовать его в обоих. Вам также понадобится #import
оба заголовка в обоих файлах .m.
Если B не импортирует A (только с @class A), существует ошибка компиляции для используемого атрибута из A.
Если вы имеете в виду «есть ошибка компиляции в каждой точке, где я использую этот атрибут типа ClassA *
», тогда да: вы не можете общаться с этим объектом, потому что вы не импортировали его интерфейс, поэтому компилятор не знает, какие сообщения вы можете отправить ClassA
экземпляру. Вот почему вам нужно импортировать его интерфейс.
Если B импортирует A, возникает ошибка компиляции на делегатской линии ClassA *.
Если оба заголовка импортируют друг друга, то у вас есть это:
ClassA.m:
ClassA.h
ClassB.h
ClassA.h (ignored because this was already imported by ClassA.m)
ClassB.m:
ClassB.h
ClassA.h
ClassB.h (ignored because this was already imported by ClassB.m)
Нет способа, которым это могло бы работать без одного интерфейса, предшествующего другому, без другого интерфейса, предшествующего ему. Это круг, с которым вы сталкиваетесь - круг, который #import
существует, чтобы разорваться. #include
разрешает круг и тем самым заклинивает:
ClassA.m:
ClassA.h
ClassB.h
ClassA.h
ClassB.h
ClassA.h
ClassB.h
ClassA.h
ClassB.h
ClassA.h
ClassB.h
ClassA.h
ClassB.h
(fails at some point)
Следовательно #import
.
Таким образом, вы не можете импортировать каждый заголовок из другого. Отсюда @class
.
Но вам все равно нужно импортировать каждый заголовок из каждого модуля. Это именно то, что вам нужно сделать: используйте @class
в каждом заголовке и #import
(на обоих заголовках) в каждом модуле.