如何从Objective C类中传递多个参数调用Swift函数?

15

例如,我在Swift中有这个方法:

@objc class MyClass: NSObject
....
@objc class func viewWithIndex(index: Int, str: String) {
    println(index, str)
}

然后我想在我的 Objective-C 类中调用该方法,我期望的调用方式如此简单:[MyClass viewWithIndex:10 str:@"string"]; 但是它无法正常工作。

我该如何调用它?请帮忙。

注意:我已经有一个可以调用 Objective-C 的有效的 Swift 函数调用 [MyClass showSomething]; 这意味着我已经成功设置了必要的桥接类设置。只有具有两个或更多参数的函数是我的问题。 :)

已解决:

我不知道发生了什么,但我刚刚重新启动了我的 Mac,并删除了 objc,这样就可以使用调用 [MyClass viewWithIndex:10 str:@"string"]; 。我记得在文档中读到过。

将您的 Objective-C 代码迁移到 Swift

  • 要在 Objective-C 中访问和使用 Swift 类,必须将其标记为 @objc 或者是 Objective-C 类的子类。

哪里出了问题?你遇到了编译时错误还是运行时错误? - Francescu
你的Swift类是NSObject的子类吗?请参考http://stackoverflow.com/questions/25605677/productmodulename-swift-h-not-exporting-all-swift-classes。 - Martin R
我已经拥有一个可工作的 Swift 函数来调用 Objective-C 类,但是没有参数或只有一个参数。现在我想尝试两个或更多参数。它报错为“没有已知的类方法 viewWithIndex:str”。 - Arnlee Vizcayno
你是否执行了 #import YOUR_PROJECT_NAME-Swift.h - vacawama
我已经导入了并创建了桥接头文件。 - Arnlee Vizcayno
我不知道发生了什么,但今天早上打开我的 Mac 并移除 @objc 后,使用调用 [MyClass viewWithIndex:10 str:@"string"]; 就正常工作了。 - Arnlee Vizcayno
3个回答

17

这对我在 Swift 3.0 中有效

public class func viewWithIndex(_ index: Int, str: String) {
    println(index, str)
}

在Swift声明中在第一个参数之前添加下划线允许我在Objective-C中进行调用,而无需命名第一个参数,像这样:

在Swift声明中在第一个参数之前添加下划线允许我在Objective-C中进行调用,而无需命名第一个参数,像这样:

[MyClass viewWithIndex:10 str:@"string"]

这确实节省了很多时间。谢谢。 - Rohan Bhale
方法参数列表开头的下划线实际上是做什么用的?..viewWithIndex(_ index..。我可以确认这对我也起作用,但这里到底发生了什么?这个标记在这个上下文中有一个名称吗? - James T Snell
2
@JamesTSnell 下划线(_)决定了在调用方法时是否应该使用参数名。在上面的例子中,即使从Swift中调用该方法也会像这样:className.viewWithIndex(10, str: "test")。如果方法定义在index和str之前都有下划线,则方法调用将如下所示:className.viewWithIndex(10,"test") - haplo1384
是否不可能调用所有参数都有名称的 Swift 函数? - mohsinulhaq

4
我相信你需要将该函数标记为public(有意义)或dynamic。否则,它将成为Swift优化的候选对象(内联或vtable方法),这将使它对Objective-C不可见。
请尝试以下方法:
public class func viewWithIndex(index: Int, str: String) {
    println(index, str)
}

或者是这个:(虽然意义不明,但也应该可行)
private dynamic class func viewWithIndex(index: Int, str: String) {
    println(index, str)
}

我不知道发生了什么事,但今天早上打开我的 Mac 并删除 @objc 后,使用调用 [MyClass viewWithIndex:10 str:@"string"]; 就可以正常工作了。 - Arnlee Vizcayno
好的,那一定是该方法已经在使用动态分派。当没有使用动态分派时,我发现上述方法有效。适用于Swift中使用KVO的相同规则应该也适用。 - Jasper Blues
我想我不需要使用 publicdynamic 或其他的关键字,因为我已经将我的类子类化为 NSObject - Arnlee Vizcayno
从Xcode6 beta 6开始,Swift仍然可以在NSObject子类上内联/ vtable方法/变量。这绝对适用于私有变量(这是有道理的),但如果您有一个希望它对Objective-C运行时除外的私有情况,则可以添加“dynamic”修饰符。 - Jasper Blues

1
在Objective-C的.h文件中,对你的类进行前向声明。
@class <MySwiftClass>

在 Objective-C 的 .m 类中导入 "Productname-swift.h",使用:

[SwiftClass storeWithData:@"Hi" password:@"secret"];

SwiftClass.swift

@objcMembers class SwiftClass{
   public class func store(data: String,password:String)->Bool{
    let saveSuccessful: Bool = KeychainWrapper.standard.set(data, forKey: password)
    return saveSuccessful;
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接