我从 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
)。所以我根本不知道为什么斯威夫特认为我这样做了,更不用说错了。
我的项目有点特别,因为我有 Objective-C 类调用C++代码(通过 Objective-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 }
如果我删除最后一行,错误消息将消失。
所以想通了,多亏了另一个问题(虽然完全不同):
-
当您尝试初始化一个类型为 ObjC 的
Class
类型的变量时,Swift 编译器真的很愚蠢,即使 NSSet 不参与,'required' initializer 'init(arrayLiteral:)' must be provided by subclass of 'NSSet'
也会出现误导性错误。我想NSSet是它知道的第一个或最后一个ObjC init方法或其他东西。
Swift 编译器也会在随机源文件(甚至是空文件!)上显示此错误,因为 Swift 解析项目中所有其他文件的"神奇"方式,因此您可以在其中引用类,而无需像 C 那样使用
include
语句。实例化
Class
的正确方法是首先对其进行类型转换:
guard let myClass = info.myClass as? (NSObject & MyClass).Type else { return }
let myInstance = myClass.init()
这比它应该的要难弄清楚得多。