我正在将Swift集成到一个现有的大型Objective C项目中,并且遇到了我认为是循环引用的问题。
有问题的课程如下:
#import "Hopscotch-Swift.h"
@interface MyController : UIViewController<MyProtocol>
...
@end
@objc protocol MyProtocol: NSObjectProtocol {
...
}
#import "MyController.h"
此代码无法编译,因为Hopscotch-Swift.h
文件不会生成。
我认为这是由于循环引用错误,因为我可以将Hopscotch-Swift.h
导入到Hopscotch-Bridging-Header.h
中未包含的目标c标头中,并且它可以正常工作。
是否有针对此问题的解决方法,还是应该向Apple提交雷达?
答案 0 :(得分:25)
在您的情况下,前向声明应该有效。
在你的.h:
@protocol MyProtocol;
@interface MyController : UIViewController<MyProtocol>
@end
在你的.m:
#import "HopScotch-Swift.h"
来自How can I add forward class references used in the -Swift.h header?和Swift互操作性指南:
如果在Swift代码中使用自己的Objective-C类型,请确保在将Swift生成的头导入到要访问Swift的Objective-C .m文件之前导入这些类型的Objective-C头。代码来自。
答案 1 :(得分:9)
我试图在Objective-C协议中使用Swift类时遇到了这个问题,其中协议也是由另一个Swift类实现的。它充满了循环引用,我猜想尝试循环生成桥接头可能是一个问题,而不是正常的&#39;通告包括问题。
对我来说,解决方案是在协议声明之前使用前向声明: -
// don't include the MyProject-Swift.h header
// forward declaration of Swift classes used
@class SwiftClass;
@protocol MyProtocol <NSObject>
- (SwiftClass *)swiftClass;
@end
答案 2 :(得分:0)
前瞻声明本身并不适用于我。它编译时没有错误,但仍然有警告称协议无法找到。我将所有警告视为错误,因此这不够好。
我能够通过将协议实现移动到另一个类别标题来修复它。
所以这对我有用:
在我的MyOtherSwiftFile.swift中:
@objc protocol MyProtocol: class {
func viewController(didFinishEditing viewController: MyViewController)
}
在我的MyViewController.h中:
@interface MyViewController // Removed protocol implementation declaration here
@end
将MyViewController + MyProtocol.h添加到项目中,并将其放在那里:
@interface MyViewController (MyProtocol) <MyProtocol>
@end
如果你愿意,方法本身可以保持原样。
实现上述内容并进行编译后,您将在代码中的某处获得编译器警告,要求MyViewController
实现MyProtocol
。在该文件中,您将#import "MyViewController+MyProtocol.h"
答案 3 :(得分:-1)
你怀疑要触发循环引用的.h文件中你可能会这样:
#ifndef MY_HEADER_H
#define MY_HEADER_H
your header file
#endif