斯威夫特认为我错误地对 NSSet 进行了子类化,但我根本没有对其进行子类化



我从 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 }

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

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

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

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

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

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

这比它应该的要难弄清楚得多。

最新更新