我有两个view controllers A
和B
,他们彼此都是代表。
除了在头文件的开头定义协议和#import
另一个头文件之外我什么都没做的时候,我得到了两个错误 -
找不到“BDelegate”的协议声明,它正在显示 A.h(我写的地方)无法找到协议声明 “ADelegate”,在B.h(我写的地方)中展示了
在网上看,人们早些时候写过,包含头文件的循环包含可能导致问题。他们建议使用#include
,或@class
声明,如 -
@class A
而不是
#import A.h
在#import B.h
我几乎尝试了这些导入的所有组合,@classes
和#include
,但仍然无法摆脱警告。此外,在线解决方案建议将#import
移至.m
文件,但这也无济于事。部分原因是在线解决方案有点模糊 - 如果你可以将其分解,那就太棒了。
有关解决此问题的建议吗?
- BigViewController.h -
#import "BaseViewController.h"
#include "BaseViewController.h"
@class BigViewController;
@protocol BigViewControllerDelegate
-(void) BigViewController:(BigViewController *) bigView;
@end
@interface BigViewController : UIViewController <BaseViewControllerDelegate>
{
//delegate
id <BigViewControllerDelegate> delegate;
ivars...
}
@properties...
@end
--------------------------------------------------
- BaseViewController.h -
#<UIKit/UIKit.h>
#import "BigViewController.h"
#include "BigViewController.h"
@class BigViewController;
@protocol BaseViewControllerDelegate
- (void) setParametersWithItemChosen:(Item *) item;
@end
@interface BaseViewController : UIViewController <...BigViewControllerDelegate...>
{
ivars...
//delegate
id <BaseViewControllerDelegate> delegate;
}
@properties...
@end
答案 0 :(得分:101)
让我进一步减少样本,并标记行:
<强> 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行试图使用它们之前声明适当的协议。
答案 1 :(得分:100)
在#import行上面写协议声明代码 e.g。
@end
@interface classname ---
答案 2 :(得分:37)
我遇到了几乎相同的问题,由于上面的答案,我修复了它,但方式略有不同。
我所做的就是在头文件中将#import行放在协议声明之后。 希望我能帮忙。如果有人因为某些原因知道这是糟糕的编程,请告诉我
答案 3 :(得分:10)
我找到了另一个解决这个问题的方法,因为我并不喜欢在类和协议声明之间只有一些#imports的想法。
基本上你只需将<YourProtocolName>
从.h类文件移动到.m文件中的类扩展名
所以在.m文件中添加
@interface YourClassName () <YourProtocolName>
@end
我不知道这是不是一个好的做法,但它看起来像是一个更清洁的解决方案,以避免进口周期。
答案 4 :(得分:8)
尝试把&lt; BaseViewControllerDelegate&gt;或者&lt; BigViewControllerDelegate&gt;在实现文件而不是头文件。它会工作。
答案 5 :(得分:3)
我在导入之前遵循了移动协议的修复程序并修复了问题...导入包含了委托,因此导致了问题。
但后来我想,为什么我还要导入代表呢?我没有引用它的属性,我没有直接调用它的任何方法(这是协议声明的用途)。
我尝试评论代理的导入并查看错误出现的位置,并发现我导入委托时导入的内容实际上是代理导入的声明,即我导入A(也是我的代理人) ),A正在导入B,我实际使用的是B.所以我将A的导入留下了注释,并为B添加了一个导入。然后我可以将导入协议顺序恢复原状。