Swift 认为我错误地继承了 NSSet 但我根本没有继承它

Swift thinks I'm subclassing NSSet wrongly but I'm not subclassing it at all

我从 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...)
                                ^

请注意,我的代码 none 是子 classing NSSet(也不是 Set。所以我完全不知道为什么 Swift 认为我在做这件事,更不用说是错误的了。

我的项目有点特别,因为我有 Objective-C classes 调用 C++ 代码(通过 Objective-C)和一个 module.map 文件让 Swift 调用 C 库。

编译Swift文件时出现错误(我从几个Swift文件中得到它,但其中只有一些使用了C库,但到目前为止它们似乎都在与ObjC classes)。正如您所看到的,Swift 没有针对其错误的行号,尽管有人在 classing NSSet。

有人看过吗?有谁知道如何诊断这个问题?我尝试注释掉部分代码,但我似乎找不到任何有助于追踪此问题的信息。

强调一下:我没有做任何 NSSet 的子classing。我想我什至没有在我的代码中使用 NSSet。这是 Swift 编译器似乎正在弥补的东西。

更新: 让我想到它可能与从 Class 对象实例化实例有关。我有一个 class,它有一个 Class,我稍后想实例化它:

@interface MYInfo : NSObject

@property Class myClass;

@end

稍后我使用 Swift 中的那个来实例化它:

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

如果我删除最后一行,错误消息就会消失。

所以想通了,多亏了另一个问题(虽然完全不同):

  1. Swift 当您尝试初始化一个类型为 ObjC 的 Class 类型的变量并出现误导性错误 'required' initializer 'init(arrayLiteral:)' must be provided by subclass of 'NSSet' 时,编译器真的很愚蠢,即使 NSSet 不是涉及。我想 NSSet 是它知道的第一个或最后一个 ObjC 初始化方法之类的。

  2. Swift 编译器还在 random 源文件(甚至是空文件!)上显示此错误,因为 "magic" 方式Swift 解析项目中的所有其他文件,因此您可以在其中引用 类 而无需像 C 那样使用 include 语句。

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

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

这比原来更难弄清楚。