Swift认为我错误地子类化了NSSet,但实际上我并没有子类化它。

10

我从Swift编译器那里得到了一个奇怪的错误消息:

<unknown>:0: error: 'required' initializer 'init(arrayLiteral:)' must be provided by subclass of 'NSSet'
Foundation.NSSet:2:33: note: 'required' initializer is declared in superclass here
    required public convenience init(arrayLiteral elements: Any...)
                                ^

请注意,我的代码中没有一个是继承自NSSet(也不是Set)的。因此,我不知道为什么Swift会认为我在这样做,更不用说是错误的了。

我的项目有些特殊,我有一些Objective-C类通过Objective-C调用C++代码,并使用module.map文件让Swift调用C库。

当编译Swift文件时出现错误(我从几个Swift文件中得到它,但只有其中一些使用C库,但所有这些文件似乎都在与ObjC类交互)。如您所见,Swift对其错误没有行号,其中有人正在继承NSSet。

有人看到过这种情况吗?有人知道如何诊断此问题吗?我尝试注释掉代码的部分内容,但似乎找不到任何有助于跟踪此问题的东西。

强调一下:我没有对NSSet进行任何子类化。我甚至认为我的代码中没有使用NSSet。这似乎是Swift编译器编造的东西。

更新:另一个问题给了我这样的想法,它可能与从Class对象实例化实例有关。我有一个类,其中包含后来要实例化的一个Class:

@interface MYInfo : NSObject

@property Class myClass;

@end

然后我使用Swift来实例化它:

guard let myClass = info.myClass.init() as? MyClass else { return }
如果我删除这最后一行,则错误信息消失。

2
请问您能展示一下子类吗?继承基础类通常比较棘手... - Sulthan
@Sulthan 我没有子类化NSSet!这就是为什么这个错误信息如此奇怪的原因! - uliwitness
我们至少需要看到你的类定义的第一行才能告诉你出了什么问题。 - rpecka
1
我删除了整个文件的内容,但错误消息仍然出现。 - uliwitness
1
既然你已经确定了问题,能否提供一个 MCVE? - matt
这真的看起来像是应该报告为错误的东西。 - Sulthan
1个回答

10

通过那个其他问题我终于理解了:

  1. 当你尝试使用ObjC的Class类型初始化一个变量时,Swift编译器非常愚蠢,并会呈现误导性错误'required' initializer 'init(arrayLiteral:)' must be provided by subclass of 'NSSet',即使NSSet并没有涉及。我猜它只是知道NSSet是第一个或最后一个ObjC的初始化方法之类的。

  2. 由于Swift以“神奇”的方式解析项目中的所有其他文件,因此您可以引用其中的类而无需像C一样使用include语句,因此Swift编译器在随机的源文件(甚至是空文件!)上也会显示这个错误。

  3. 实例化一个Class的正确方法是首先进行类型转换:

guard let myClass = info.myClass as? (NSObject & MyClass).Type else { return }
let myInstance = myClass.init()

这比应该的要难解决得多。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接