Ak1*_*Ak1 59 cocoa-touch protocols objective-c
我有两个view controllers A和B,他们都拥有对方作为自己的代表.
当我除了在头文件的开头和#import另一个头文件中定义协议之外什么都没做的时候,我得到两个错误 -
找不到"BDelegate"的协议声明,它在Ah(我写的地方)中显示无法找到"ADelegate"的协议声明,这是在Bh(我写的地方)中显示的
在线查看,人们早些时候写过,包含头文件的循环包含可能会导致问题.他们建议使用#include相反,或@class声明像 -
@class A
Run Code Online (Sandbox Code Playgroud)
代替
#import A.h
Run Code Online (Sandbox Code Playgroud)
内 #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
--------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
- 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
Run Code Online (Sandbox Code Playgroud)
Ano*_*mie 101
让我进一步减少样本,并标记线条:
VC1.h
#import "VC2.h" // A
@class VC1;
@protocol VC1Delegate // B
@end
@interface VC1 : UIViewController <VC2Delegate> // C
@end
Run Code Online (Sandbox Code Playgroud)
VC2.h
#import "VC1.h" // D
@class VC2;
@protocol VC2Delegate // E
@end
@interface VC2 : UIViewController <VC1Delegate> // F
@end
Run Code Online (Sandbox Code Playgroud)
考虑当#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
Run Code Online (Sandbox Code Playgroud)
VC1.h
#import "VC1Delegate.h"
#import "VC2Delegate.h"
@interface VC1 : UIViewController <VC2Delegate> // C
@end
Run Code Online (Sandbox Code Playgroud)
VC2Delegate.h
@class VC2;
@protocol VC2Delegate // E
@end
Run Code Online (Sandbox Code Playgroud)
VC2.h
#import "VC1Delegate.h"
#import "VC2Delegate.h"
@interface VC2 : UIViewController <VC1Delegate> // F
@end
Run Code Online (Sandbox Code Playgroud)
如果现在跟踪导入,您将看到在@interface行尝试使用它们之前,现在将始终声明相应的协议.
Vin*_*ner 101
在#import行上面写协议声明代码,例如
@结束
@interface classname ---
小智 37
我有几乎相同的问题,由于上面的答案,我修复了它,但方式略有不同.
我所做的只是将#import行放在头文件中的协议声明之后.希望我能帮忙.如果有人知道由于某种原因这是不好的编程,请告诉我
Pot*_*las 10
我找到了另一个解决这个问题的方法,因为我真的不喜欢在类和协议声明之间只有一些#imports的想法.
基本上你只是<YourProtocolName>从.h类文件移动到.m文件中的类扩展名
所以在你的.m文件中添加
@interface YourClassName () <YourProtocolName>
@end
Run Code Online (Sandbox Code Playgroud)
我不知道这是不是一个好的做法,但它看起来像一个更清洁的解决方案,以避免导入周期.
| 归档时间: |
|
| 查看次数: |
51525 次 |
| 最近记录: |