【问题标题】:Swift thinks I'm subclassing NSSet wrongly but I'm not subclassing it at all斯威夫特认为我错误地继承了 NSSet 但我根本没有继承它
【发布时间】:2019-09-13 20:19:46
【问题描述】:

我从 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 认为我在做这件事,更不用说错了。

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

编译 Swift 文件时发生错误(我从几个 Swift 文件中得到它,但只有其中一些使用 C 库,但到目前为止,它们似乎都在与 ObjC 类对话)。正如你所看到的,Swift 没有行号,因为它的错误是有人将 NSSet 子类化。

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

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

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

@interface MYInfo : NSObject

@property Class myClass;

@end

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

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

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

【问题讨论】:

  • 你能显示子类吗?子类化基础类通常很棘手......
  • @Sulthan 我不是继承 NSSet!这就是为什么这个错误信息如此离奇!
  • 我们至少需要查看你的类定义的第一行来告诉你出了什么问题
  • 我删除了整个文件的内容,仍然出现错误信息。
  • 既然您已经隔离了问题,您可以提供一个 MCVE 吗?

标签: ios objective-c swift objective-c++ swift5


【解决方案1】:

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

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

  2. Swift 编译器也会在 random 源文件(甚至是空文件!)上显示此错误,因为 Swift 解析项目中所有其他文件的“神奇”方式,因此您可以参考没有像 C 这样的 include 语句的类。

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

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

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

【讨论】:

    猜你喜欢
    • 2018-02-20
    • 1970-01-01
    • 2019-10-29
    • 1970-01-01
    • 1970-01-01
    • 2014-12-26
    • 1970-01-01
    • 1970-01-01
    • 2020-08-24
    相关资源
    最近更新 更多