【问题标题】:How to expose swift functions ONLY to objc如何仅向 objc 公开 swift 函数
【发布时间】:2015-09-03 20:18:32
【问题描述】:

我有一个在 Objective C 应用程序中使用的 swift 框架。我有一个 Location 类,它有两个参数:

///Latitude in Decimal Degrees
public var lat : Double?

///Longitude in Decimal Degrees
public var lon : Double?

Objective C 无法访问它们,因为它们是可选的。我希望让一个仅限 swift 的类在这里工作,所以我的“解决方法”是为该类添加一些 @objc 方法 - 但我不希望它们可以被快速访问。

///Objective C Extensions to allow easier Access
extension LocationMessage {

@objc var getLat : Double {
    if (lat != nil) {
        return lat!
    }
    return -91;
 }

@objc var getLon : Double {
    if (lon != nil) {
        return lon!;
    }
    return -181;
}
}

那么问题来了:

1) 我可以将此扩展放入框架中,但有什么方法可以“隐藏”swift 使其无法调用它?

2) 我想我可以在我的 Objective C 应用程序中编写一个 swift 文件 - 将扩展添加到类 - 这会是要走的路吗?

3) 还有其他方法吗?

【问题讨论】:

  • 我会说 2 号是要走的路。您是否尝试将扩展设为私有?

标签: ios objective-c xcode swift


【解决方案1】:

从 Swift 3.1 开始,这可以使用 @available 属性来实现。 official documentation on attributes 提到了很多不同的选项,但没有明确说明如何将所有选项结合起来。然而,在 3.1 中实现的 this Swift evolution proposal 讨论了将某些东西标记为某个版本的 Swift 的过时:

@available(swift, obsoleted: 3.1)
class Foo {
    //...
}

在此示例中,尝试在 Swift 3.1 或更高版本中使用 Foo 类会出错。稍作调整,我们就可以做到这一点:

@available(swift, obsoleted: 1.0)
@objc(exampleMethodWithObject:)
static func exampleMethod(with object: NSObject) {
    //...
}

在本例中,尝试在 Swift 1.0 或更高版本中使用方法 exampleMethodWithObject: 会出错,而在 Objective-C 中使用则不会。 (如果你真的想确定,可以指定obsoleted: 0.1。使用0.0或者不写版本号都行不通。)

所以对于您的代码,这应该可以工作:

extension LocationMessage {

    @available(swift, obsoleted: 1.0)
    @objc var getLat : Double {
        if (lat != nil) {
            return lat!
        }
        return -91
    }

    @available(swift, obsoleted: 1.0)
    @objc var getLon : Double {
        if (lon != nil) {
            return lon!
        }
        return -181
    }

}

【讨论】:

  • 自 swift 4 以来,'swift' 平台仅可用于此属性。所以你应该使用 * 代替('obsoleted' 参数仅适用于 swift 版本,因此它可以工作)
【解决方案2】:

@available (*, unavailable) 使外部 swift 世界无法使用代码,但 @objc 指令使目标 c 可以访问它。

@available (*, unavailable)
@objc public extension LocationMessage {

var getLat : Double {
    if (lat != nil) {
        return lat!
    }
    return -91;
 }

var getLon : Double {
    if (lon != nil) {
        return lon!;
    }
    return -181;
}
}

【讨论】:

  • 这似乎不适用于 Xcode 12.2。生成的 Objective-C 标头包含 SWIFT_UNAVAILABLE 属性,并且该方法在两种语言中都不可用。
  • @DavidSnabel-Caunt 这种方法在 xcode 12.2 中对我来说仍然非常有效。
  • @berec 刚刚检查了 12.5.1 - 不工作。它说has been explicitly marked unavailable
猜你喜欢
  • 2011-07-16
  • 1970-01-01
  • 1970-01-01
  • 2013-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多