接收器类型 '' 例如消息是前向声明(但标头在 .m 中导入)

Posted

技术标签:

【中文标题】接收器类型 \'\' 例如消息是前向声明(但标头在 .m 中导入)【英文标题】:Receiver type '' for instance message is a forward declaration (but header is imported in .m)接收器类型 '' 例如消息是前向声明(但标头在 .m 中导入) 【发布时间】:2021-08-17 20:13:33 【问题描述】:

我查看了很多关于此的帖子,它通常似乎围绕着缺少 .h.m 中的导入

在我的例子中,我正在尝试导入一个 swift 目标 C 函数,但我相信 .h.mswift 文件配置正确(生成的 swift-header 也是如此)。

我的 Swift 类被标记为 @objc 并扩展了 NSObject

当我在.h 中使用前向声明导入类,在.m 中使用MyApp.h 导入时,它可以看到该类。但是,它看不到我想要的方法,它给了我错误 Receiver type 'class' 例如消息是前向声明。

当我检查生成的头文件时,会在那里生成方法(并且该方法被标记为@objc 并返回@objc 兼容值)。

您能否提出可能导致此问题的原因?

这是我的代码的参考:

斯威夫特

@objc class ObjcHelper: NSObject 
    @objc static let shared = ObjcHelper()

    @objc public func getObjcFromNSString(nsString: NSString) -> ObjcType 
       return ObjcType()
    

.h 中,我想在目标 c 文件中使用它:

@class ObjcHelper

在 .m 中我正在导入应用标头

#import <App-Swift.h>

当我尝试使用.m 文件中的代码时,编译器可以很好地看到这部分:

[ObjcHelper shared] // 编译器认为这很好!

但是,如果我尝试调用该方法,即使我输入它,它也不会自动完成或找到它。

如果我查看生成的标头,我会看到这里的方法是这样的:

SWIFT_CLASS("_TtC7ObjcHelper")
@interface ObjcHelper : NSObject
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, strong) ObjcHelper * _Nonnull shared;)
+ (\ObjcHelper * _Nonnull)shared SWIFT_WARN_UNUSED_RESULT;
- (enum ObjcType)getObjcFromNSStringWithNsString:(NSString * _Nonnull)nsString SWIFT_WARN_UNUSED_RESULT;
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end

我希望不工作的代码如下(并且会产生错误):

ObjcType value = [[ObjcHelper shared] getObjcFromNSStringWithNsString: @"abc"]];

【问题讨论】:

Swift 代码说它返回ObjcType,但是生成的头文件显示enum PaymentTypeObjc,也许您正在查看一个过时或不同步的App-Swift 头文件?跨度> 这只是我试图使其更通用的一个错字,我很抱歉。 好的,所以ObjcType 是一个枚举?它的定义是在 App-Swift.h 头文件中正确生成的吗?此外,您似乎还有一个错字 - ObjcType *value 不正确,枚举是按值返回的,而不是按引用返回的。 是的 ObjcType 是一个枚举,是的,它在标题中。单独的枚举也会被检测并编译。它唯一的 ObjcHelper 是看不见的 【参考方案1】:

这个问题很微妙,但似乎已经解决了。

在我的项目中,有许多目标,而对于 ObjcHelper,它并没有针对其中一个目标。我相信发生的事情是,即使创建了桥接目标 c 帮助文件,也存在缺少“必需”目标所有者的引用的问题,并且此错误会向前传播,因为无法找到该类。

因此,如果您遇到此问题,请检查以确保您尝试引入 Objective-c 的 Swift 类的目标成员资格设置为它需要的所有目标(否则您可能会收到关于前向类的误导性错误声明)。

【讨论】:

以上是关于接收器类型 '' 例如消息是前向声明(但标头在 .m 中导入)的主要内容,如果未能解决你的问题,请参考以下文章

基础类消息是前向声明错误

是否可以在 C/C++ 中永远不使用标头保护?如果是这样,这种方法有啥优势吗?

子类化视图控制器:前向声明

包含消息长度的两字节标头上的部分 recv() 怎么样?

前向声明 cv::Mat

前向声明/何时最好包含标题?