Позвольте мне уменьшить выборку еще больше и обозначить строки:
VC1.h
#import "VC2.h" // A
@class VC1;
@protocol VC1Delegate // B
@end
@interface VC1 : UIViewController <VC2Delegate> // C
@end
VC2.h
#import "VC1.h" // D
@class VC2;
@protocol VC2Delegate // E
@end
@interface VC2 : UIViewController <VC1Delegate> // F
@end
Рассмотрим, что происходит, когда что-то #imports VC1.h: достигает строки A, затем выполняется импорт.Строка D ничего не делает, потому что VC1.h уже был импортирован.Затем строка E обрабатывается.Затем строка F, и мы получаем ошибку, потому что мы еще не дошли до строки B, поэтому протокол не объявлен!
Рассмотрим, что происходит, когда что-то #imports VC2.h: Достигает строки D, затемимпорт обработан.Строка A ничего не делает, потому что VC2.h уже был импортирован.Затем строка B обрабатывается.Затем строка C, и мы получаем ошибку, потому что мы еще не дошли до строки E, поэтому протокол не объявлен!
Первым шагом является пересмотр того, действительно ли оба этих класса должны быть делегатами друг друга.,Если вы можете разорвать цикл, это, вероятно, будет путь.Если нет, вам нужно реструктурировать заголовки.Наиболее простой способ - это, вероятно, поместить делегатов в собственные заголовки:
VC1Delegate.h
@class VC1;
@protocol VC1Delegate // B
@end
VC1.h
#import "VC1Delegate.h"
#import "VC2Delegate.h"
@interface VC1 : UIViewController <VC2Delegate> // C
@end
VC2Delegate.h
@class VC2;
@protocol VC2Delegate // E
@end
VC2.h
#import "VC1Delegate.h"
#import "VC2Delegate.h"
@interface VC2 : UIViewController <VC1Delegate> // F
@end
Если вы отслеживаете импорт сейчасвы увидите, что соответствующие протоколы теперь будут всегда объявляться до того, как строки @interface попытаются их использовать.