我已经在Swift中定义了两个不同的功能,只是为了测试如何从Objective-C调用...其中一个有效,一个没有!
我在这里定义了它们:
public extension UIViewController {
func testAddingOperationTo(array: inout [Operation]) -> Operation {
let completionBlock = BlockOperation (block: {
print("completionOperation")
})
return completionBlock;
}
func testSomethingWith (count: Int){
print("testing something \(count)")
}
}
在Objective-C中,我导入了正确的头文件,我可以调用第二种方法:
[self testSomethingWithCount:0];
但是第一个不起作用......它没有在Xcode自动完成中显示,即使我手动输入它,它也会产生构建错误。我想这样称呼它:
NSOperation *completionOperation = [self testAddingOperationToArray: operationsList];
这里有什么问题?我是否错误地定义了该函数,或者是否存在一些我不知道的关于Swift的模糊规则?
答案 0 :(得分:2)
您可以将@objc
放在方法声明的前面,告诉Swift编译器您特别想要使用Objective-C中的方法。除了其他效果之外,如果由于某种原因无法从Objective-C调用该方法,这会使编译器发出错误:
@objc func testAddingOperationTo(array: [Operation]) -> Operation {
// Method cannot be marked @objc because the type of the parameter cannot be represented in Objective-C
如果编译器告诉你哪个参数的类型没有表示会很好,但是从Xcode 9 beta 2开始,它就没有了。
无论如何,在这种情况下的问题是Swift inout
参数不能在Objective-C中表示。如果您不需要参数为inout
,只需取出该关键字,该方法将桥接到Objective-C。
如果需要传入函数可以修改的数组,一种方法是添加另一个版本NSMutableArray
。第二个版本桥接到Objective-C:
func testAddingOperation(to array: inout [Operation]) {
let completionBlock = BlockOperation (block: {
print("completionOperation")
})
array.append(completionBlock)
}
@objc func testAddingOperation(toOperations mutableArray: NSMutableArray) {
var array = mutableArray.map({ $0 as! Operation })
testAddingOperation(to: &array)
mutableArray.replaceObjects(in: NSRange(location: 0, length: mutableArray.count), withObjectsFrom: array)
}
答案 1 :(得分:1)
导入标题大部分时间 。但是,也有一些例外。
例外情况是使用的类型是桥接类型(例如,NSString
和String
)。您的inout
必须重写为UnsafeMutablePointer
,因为目标C无法识别inout
。因此,您必须使用Objective C类型或为两种类型编写函数。