采用可变参数的Swift ambiguos方法

时间:2016-03-30 12:57:56

标签: objective-c swift variadic-functions variadic

我有以下方法

static func t(key: String, params: AnyObject...) -> String{
    let string = .......
    if (params.count == 0){
        return string
    } else {
        return String(format: string, params)
    }
}

问题是我需要在Objective C中使用这个方法,这对于可变参数是不可能的。我试图做的是为目标c创建另一种方法,其中params是一个数组。但是当没有参数时我还需要第三个。

@objc static func t(key: String, params: [AnyObject]) -> String
@objc static func t(key: String) -> String

但现在很快就抱怨方法t含糊不清,因为第一种和第三种方法只能占用密钥。

如何使这项工作?我知道我可以使用不同的名字,但我想保持一致。

更新: 另一个问题是我无法在函数内部正确调用String(format:...),因为params是一个数组而不是一组参数。有什么好方法可以解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

您可以执行以下操作:

this.then(...)

......来自Swift的电话:

@objc(C)
public class C : NSObject {

    public static func t(key: String, params firstParam: AnyObject, _ params: AnyObject...) -> String {
        return t(key, params: [firstParam] + params)
    }

    @objc
    public static func t(key: String, params: [AnyObject]) -> String {
        return "TODO"
    }

    @objc
    static func t(key: String) -> String {
        return t(key, params: [])
    }
}

这是桥接如下:

C.t("")
C.t("", params: 1)
C.t("", params: 1, 2)
C.t("", params: [1, 2, 3])

可以通过以下方式发送消息:

SWIFT_CLASS_NAMED("C")
@interface C : NSObject
+ (NSString * _Nonnull)t:(NSString * _Nonnull)key params:(NSArray * _Nonnull)params;
+ (NSString * _Nonnull)t:(NSString * _Nonnull)key;
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end

关于问题的更新,有一个格式化#import "DarkSide.h" #import "ObjCInterOp-Swift.h" @implementation DarkSide - (instancetype)init { self = [super init]; if (self) { [C t:@"" params:@[]]; [C t:@""]; } return self; } @end 初始化程序的版本需要String而不是[CVarArgType]

CVarArgType...

只有func f(format format: String, _ params: [CVarArgType]) -> String { return String(format: format, arguments: params) } f(format: "%d %d %d", [1, 2, 3]) // "1 2 3" 无法在Objective C中表示,这确实使事情变得复杂。事实上,如果你真的必须使用CVarArgType 从目标C中获取它,那么我现在还不知道如何避免从String.init(format: String, arguments: [CVarArgType])转到AnyObject符合以下黑暗代码:

CVarArgType

我的建议是要么放弃@objc(C) public class C : NSObject { public static func t(key: String, params: CVarArgType...) -> String { return t(key, params: params) } public static func t(key: String, params: [CVarArgType]) -> String { return String(format: key, arguments: params) } @objc(t:params:) public static func t_objc(key: String, params: [AnyObject]) -> String { let args = params.map{ // here you'll probably need to parse `key` so as to // know what to cast into! ($0 as! NSNumber).integerValue as CVarArgType } return t(key, params: args) } @objc(t:) static func t_objc(key: String) -> String { return t(key) } } 之类的东西,要么在Objective C中实现基本方法......