您可以执行以下操作:
@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: [])
}
}
...从 Swift 调用:
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"
只有CVarArgType 不能在Objective C 中表示,这确实使事情变得复杂。事实上,如果你真的必须使用 String.init(format: String, arguments: [CVarArgType]) 并且 从 Objective C 中获取它,那么我目前不知道如何避免从 AnyObjects 转换为 CVarArgTypes以下模糊代码行:
@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)
}
}
我的建议是要么放弃 String.init(format: String, arguments: [CVarArgType]) 之类的东西,要么在 Objective C 中实现基本方法...