【问题标题】:Call Swift func from Objective-C with parameter使用参数从 Objective-C 调用 Swift 函数
【发布时间】:2018-11-10 20:53:11
【问题描述】:

我想将 Swift 类集成到 UIViewController 类中。 我想我所有的设置都是正确的。我有一个带有函数的类 rURLTask:NSObject:

@objc public func primer() {
    print("primer")
}

在我的 .swift 文件中,并且可以从我的 Objective-C 类调用它:

[URLTask primer];

而且打印效果很好。 另一个功能是:

@objc public func ladeURL(url: URL?) {
    print("loadURL")
}

但是我不能从 Objective-C 调用这个。我试着写:

NSURL* testURL = [NSURL URLWithString:@"http://www.google.com"];    
[URLTask ladeURL:testURL];

我得到错误:

“rURLTask”没有可见的@interface 声明选择器“ladeURL:”

我认为有一个非常基本的错误。在另一个项目中使用 Swift 3 中的 Objective-C 效果很好。

【问题讨论】:

标签: objective-c swift objective-c-swift-bridge


【解决方案1】:

你不能打电话的原因

@objc public func ladeURL(url: URL?) {
    print("loadURL")
}

说出来

[URLTask ladeURL:testURL];

ladeURL:就 Objective-C 而言不是此方法的名称。 这就是编译器说“'rURLTask' 没有可见的@interface”时的意思声明选择器ladeURL:"。

就 Objective-C 而言,它的名字是ladeURLWithUrl:。那是因为您将url: 参数名称暴露为外部标签。


如果能说出来对你很重要

[URLTask ladeURL:testURL];

在 Objective-C 中,您可以这样声明 ladeURL

@objc public func ladeURL(_ url: URL?) {
    print("loadURL")
}

看到下划线了吗?这隐藏了参数的外部标签。


另一个允许您保留url: 外部标签的解决方案是将Objective-C 名称声明为objc 属性的一部分:

@objc(ladeURL:) public func ladeURL(url: URL?) {
    print("loadURL")
}

这对编译器说:“我知道你会喜欢将此方法的名称翻译成 Objective-C 为 ladeURLwithUrl:,但不要;将其翻译为 ladeURL: 。”

【讨论】:

  • 关于 Swift 和 Objective-C 如何查看彼此方法名称的一些技巧可以在我的讨论中找到:apeth.com/swiftBook/apa.html#_objective_c_methods
  • 优秀的答案(像往常一样。)投票。
  • @DuncanC 谢谢。我确实想到这里的规则(用于在两种语言之间翻译方法名称)随着时间的推移发生了变化。我认为在 Swift 2 中,OP 的原始代码会起作用,我记得对吗?但我认为鞭打那匹马不值得。
【解决方案2】:

当你将类导入 OC 时,用 swift 编写的方法的名称被翻译成与 withParameterType 连接,作为素数 方法

@objc public func primer() {
  print("primer")
}

没有参数可以这样调用

[URLTask primer];

但是这个

@objc public func ladeURL(url: URL?) {
   print("loadURL")
}

被翻译成

[URLTask ladeURLWithUrl:<#NSURL#>];

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-08
    • 2014-07-27
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 2020-06-22
    相关资源
    最近更新 更多