#import 不能防止循环调用?
我有两个类 ClassA 和 Class B(它们是 viewController)。
A 类是 B 类的委托。
ClassA“laucnhes”和 ClassB 的实例。
ClassB 调用 classA 上的方法。
假设是这样:
#import "ClassB.h"
@interface ClassA : NSObject {
ClassB* subController;
}
- (void) doThis;
-------------------------------
#import "ClassA.h"
@interface ClassB : NSObject {
ClassA* delegate;
}
-------------------------------
@implementation ClassB
- (void) someMethod {
AnObject* myObj = [self.delegate.arr objectAtIndex:8];
[self.delegate doThis];
}
这样做,A 必须导入 B,B 必须导入 A。
如果 B 不导入 A(仅使用 @class A),则 A 中使用的属性会出现编译错误。
如果 B 导入 A,则 ClassA* delegate
行上会出现编译错误。
为什么我会出现这些编译错误? #import 不会再次保护递归调用吗?
我不需要解决方案来解决该问题,我知道如何做到这一点。
但我想知道为什么我的 #import 会导致这些问题。这些不是#includes...
I have two classes ClassA and Class B (they are viewControllers).
Class A is a delegate of classB.
ClassA "laucnhes" and instance of ClassB.
ClassB call methods on classA.
Let's say it's :
#import "ClassB.h"
@interface ClassA : NSObject {
ClassB* subController;
}
- (void) doThis;
-------------------------------
#import "ClassA.h"
@interface ClassB : NSObject {
ClassA* delegate;
}
-------------------------------
@implementation ClassB
- (void) someMethod {
AnObject* myObj = [self.delegate.arr objectAtIndex:8];
[self.delegate doThis];
}
Doing that way, A must import B, and B must import A.
If B do not import A (with just @class A), there is a compile error for the used attribute from A.
If B imports A, there is a compile error on the ClassA* delegate
line.
Why do I have those compile errors? Doesn't #import protect again recursive calls ?
I don't need a solution to solve that problem, I know how I may do this.
But I wonder why my #import cause those problems. These are not #includes...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在 .h 文件中,更喜欢 @class 而不是 #import。然后可以将两者导入到 .m 实现文件中。
使用 @class 语句而不是 #import 还可以减少依赖性并使其余的语句更加清晰。它还可以加快编译时间。
In .h files prefer @class to #import. Both can then be imported in the .m implementation files.
Using @class statements instead of #import also reduces dependencies and makes the remaining ones more clear. It can also speed up compile times.
#import
可防止重复将相同标头导入同一模块,无论是否通过循环包含/导入。它通过不让您这样做来防止这种情况:只有标头的第一个#import
有效;同一标头的后续#import
将被忽略。在循环#include 的情况下,预处理器会绕圈数次,然后在进行编译之前构建失败。使用#import 可以防止预处理器陷入困境并让预处理器成功,但循环-#import 代码充其量仍然是狡猾的,通常无法编译。
那么,就看你的具体情况了。
对于您在问题中显示的代码,
@class
将在一个或两个标头中工作,实际上您应该在两个标头中使用它。您还需要#import
两个 .m 文件中的两个标头。如果您的意思是“在我使用
ClassA * 类型的属性的每个点上都会出现编译错误”
”,那么是的:您无法与该对象通信,因为您尚未导入其接口,因此编译器不知道您可以向ClassA
实例发送哪些消息。这就是为什么你需要导入它的接口。如果两个标头相互导入,那么就会出现以下情况:如果
一个接口在另一个接口之前,而另一个接口在其之前,则此操作无法工作。这就是您正在陷入的循环——
#import
存在的目的就是要打破这个循环。#include
允许圆,从而楔入:因此
#import
。因此,您无法从另一个导入每个标头。因此
@class
。但您仍然需要从每个模块导入每个标头。事实上,这正是您需要做的:在每个标头中使用
@class
并在每个模块。#import
protects against repeatedly importing the same header into the same module, whether by circular includes/imports or not. It protects against that by not letting you do it: Only the first#import
of a header works; subsequent#import
s of the same header are ignored.In a circular
#include
situation, the preprocessor would go around the circle some number of times and then fail the build before you even get to compilation. Using#import
prevents the preprocessor from getting wedged and lets the preprocessor succeed, but circular-#import
code is still dodgy at best and usually will not compile.So, on to your specific situation.
For the code you showed in your question,
@class
will work in either or both headers, and indeed you should use it in both. You'll also need to#import
both headers in both .m files.If you mean “there is a compile error at each point where I use that attribute of type
ClassA *
”, then yes: You can't talk to that object because you haven't imported its interface, so the compiler doesn't know what messages you can send to aClassA
instance. That's why you need to import its interface.If both headers import each other, then you have this:
There is no way this can work without one interface preceding the other without the other interface preceding it. That's the circle you're running into—the circle that
#import
exists to break.#include
allows the circle, and thereby gets wedged:Hence
#import
.So you cannot import each header from the other. Hence
@class
.But you still need to import each header from each module. That is, in fact, exactly what you need to do: Use
@class
in each header and use#import
(on both headers) in each module.声明可以避免此编译投诉
通过在 .h 文件中 。然后可以将 ClassB.h 包含到 .m 文件中。
所以你在这一点上是对的。与都市神话相反,#imports 的工作方式与 #includes 非常相似,因为编译器必须检查文件。
请参阅此(重复?)针对你的哲学问题提出问题。
This compile complaint can be avoided by declaring
in the .h file. The ClassB.h can then be included into the .m file.
So you are right on that one. Contrary to urban myth, #imports work pretty much like #includes in the sense that the compiler has to check the file.
See this (duplicate?) question for your philosophical problem.
我认为您会发现 #import 仅在已经成功包含一次后才能防止多次包含,可以这么说。
即,在您的情况下,在要求再次导入之前它尚未成功导入 classa.h,因此它会这样做。
I think you'll find that #import only protects against multiple inclusion once it has already been successfully included once, so to speak.
ie, in your case, it hasn't successfully imported classa.h before it is asked to import it again, so it does so.