【问题标题】:Subclassing an Objective C class using Swift in a framework target在框架目标中使用 Swift 子类化 Objective C 类
【发布时间】:2020-10-29 23:19:14
【问题描述】:

我有一个框架目标,其中大部分类都是用 Objective C 编写的。最近我们开始在代码中引入 Swift 文件。我们使用模块使私有的 Objective C 文件可用于 swift 代码(更多关于这可以找到here)。

直到最近,当我尝试使用 Swift 对我的一个 Objective C 类进行子类化时,这种方法一直很好,我在 Generated MyFramework-Swift.h 文件中遇到错误,上面写着 “Module TestSwift not found”其中TestSwift 是我在modulemap 文件中提供的模块的名称。但是,如果我尝试对我的框架(公共类)的总括标题中列出的类进行子类化,它可以工作。

import TestSwift

@objc public class NewSwiftClass: ExistingObjectiveCClass {
    //throws error in the generated MyFramework-Swift.h file while compiling
}

如果我将我的 swift 类保留在内部,它可以工作

import TestSwift

@objc class NewSwiftClass: ExistingObjectiveCClass {
    //works fine
}

但我想在我的 Objective C 文件中使用这个 Swift 类,因此不能将其保留在内部。

TL;DR:我无法在框架目标中使用 Swift 对现有的 Objective C 类进行子类化。

【问题讨论】:

    标签: objective-c swift xcode clang language-interoperability


    【解决方案1】:

    我相信这在 Swift 中是不可能的,因为在 Objective-C 中是不可能的。

    如果您的框架中有一个类 A 不属于您的伞形标题,并且您希望 B 对其进行子类化并您的伞形标题中,您不能去做吧。

    您必须在接口声明@interface B: A 中声明继承,该声明位于 B 的标头中,因此位于伞形标头中。但是编译器会抱怨:“什么是A?”您可以在那里导入 A 的标头,但与 Swift 的 import 不同,Objective-C 的 #import 将 A 标头的内容直接放入 B 标头中。这意味着 A 现在也在伞形标题中,即公开。

    将 Swift 与 Objective-C 结合起来并不神奇。编译器仍然需要能够生成准确描述 Swift 接口的有效 Objective-C 标头。所以除非你能想办法让 Objective-C 做到这一点,否则你不能在 Swift 中做到。

    我能想到的唯一选择是将您的“是”关系更改为“具有”关系,即

    @objc public class NewSwiftClass {
        let parent: ExistingObjectiveCClass
    }
    

    显然,您失去了实际继承的大部分好处,但您仍然可以使用父代作为super 的替代品。您还可以声明两个类都遵循的公共协议,以确保您在它们的方法之间获得一致性。

    【讨论】:

    • 谢谢,@Max 所以如果我理解正确的话,我不能使用 swift 类对 Objective c 类进行子类化,直到 1. 我将 Objective c 接口(即 .h 文件)公开 2. 我让内部的 swift 类。
    • 但是如果我们按照这个类比,我想知道如何在我的公共 swift 类中声明同一个私有 objc 类的公共属性?它是如何工作的?
    • @SagarD 没有限定符,正如我的回答,该属性是 internal 并且在框架之外不可见。如果编译器抱怨,您可能必须将其显式声明为私有
    猜你喜欢
    • 1970-01-01
    • 2018-11-07
    • 1970-01-01
    • 2015-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多