使用参数从Objective-C调用Swift函数

hei*_*imi 2 objective-c swift objective-c-swift-bridge

我想将Swift类集成到UIViewController类中。我认为所有设置都正确。我有一个带有功能的rURLTask:NSObject类:

@objc public func primer() {
    print("primer")
}
Run Code Online (Sandbox Code Playgroud)

在我的.swift文件中,可以使用以下命令从我的Objective-C类进行调用:

[URLTask primer];
Run Code Online (Sandbox Code Playgroud)

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

@objc public func ladeURL(url: URL?) {
    print("loadURL")
}
Run Code Online (Sandbox Code Playgroud)

但是我无法从Objective-C调用此代码。我试着写:

NSURL* testURL = [NSURL URLWithString:@"http://www.google.com"];    
[URLTask ladeURL:testURL];
Run Code Online (Sandbox Code Playgroud)

我得到错误:

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

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

mat*_*att 5

你不能打电话的原因

@objc public func ladeURL(url: URL?) {
    print("loadURL")
}
Run Code Online (Sandbox Code Playgroud)

通过说

[URLTask ladeURL:testURL];
Run Code Online (Sandbox Code Playgroud)

是,ladeURL:不是该方法的名字就Objective-C的关注。这就是编译器说“ rURLTask的无可见@interface声明选择器ladeURL:”时的意思。

就Objective-C而言,它的名称是ladeURLWithUrl:。这是因为您已将url:参数名称公开为外部标签。


如果您说的很重要

[URLTask ladeURL:testURL];
Run Code Online (Sandbox Code Playgroud)

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

@objc public func ladeURL(_ url: URL?) {
    print("loadURL")
}
Run Code Online (Sandbox Code Playgroud)

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


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

@objc(ladeURL:) public func ladeURL(url: URL?) {
    print("loadURL")
}
Run Code Online (Sandbox Code Playgroud)

这说的编译器:“我知道你会喜欢把这种方法引入的Objective-C作为名称ladeURLwithUrl:,但不要;因为它翻译ladeURL:吧。”