假设我有一个Objective-c中的类,其中有一个静态方法如下:
+ (NSError *)executeUpdateQuery:(NSString *)query, ...;
我该如何在Swift中调用它?自动完成不能识别它,编译器也不满意:
MyClassName.executeUpdateQuery("")
抱怨'MyClassName.Type没有名为executeUpdateQuery的成员'
假设我有一个Objective-c中的类,其中有一个静态方法如下:
+ (NSError *)executeUpdateQuery:(NSString *)query, ...;
我该如何在Swift中调用它?自动完成不能识别它,编译器也不满意:
MyClassName.executeUpdateQuery("")
抱怨'MyClassName.Type没有名为executeUpdateQuery的成员'
编写一个 va_list 版本的可变参数方法;
+ (NSError *)executeUpdateQuery:(NSString *)query, ...
{
va_list argp;
va_start(argp, query);
NSError *error = [MyClassName executeUpdateQuery: query args:argp];
va_end(argp);
return error;
}
+ (NSError *)executeUpdateQuery:(NSString *)query args:(va_list)args
{
NSLogv(query,args);
return nil;
}
这可以从Swift中调用
MyClassName.executeUpdateQuery("query %d, %d %d", args: getVaList([1,2,3,4]))
添加一个扩展以支持本地的Swift可变参数:
protocol CFormatFunction {
class func executeUpdateQuery(_ format: String, _ args: CVarArg...) -> NSError?
}
extension MyClassName : CFormatFunction {
class func executeUpdateQuery(_ format: String, _ args: CVarArg...) -> NSError?
{
return withVaList(args) { MyClassName.executeUpdateQuery(format, args: $0) }
}
}
MyClassName.executeUpdateQuery("query %d %@ %.2f", 99, "Hello", 3.145)
注意,Swift 不提供 NS_FORMAT_FUNCTION 警告 (-Wformat)
MyClassName.executeUpdateQuery("query %@", 99)
CVArgType
在 Swift 中本地展示 C “varargs” API 中非常有用。(Swift 文档)
如果您有
+ (int)f1:(int)n, ...;
首先需要创建一个va_list
版本:
+ (int)f2:(int)n withArguments:(va_list)arguments
通过从可变参数版本调用 va_list 版本,可以 避免重复代码。如果您没有编写原始的可变参数函数,则可能无法实现此操作(在此参考资料中有解释)。
一旦您拥有了这个方法,您就可以编写这个 Swift 包装器:
func swiftF1(x: Int, _ arguments: CVarArgType...) -> Int {
return withVaList(arguments) { YourClassName.f2(x, withArguments :$0) }
}
arguments
之前有_
),这使得swiftF1
的调用语法就像普通的C变参函数一样:swiftF1(2, some, "other", arguments)
在Objective C中
MyClassName.h
+ (BOOL)executeSQL:(NSString *)sql args:(va_list)args;
MyClassName.m
+ (BOOL)executeSQL:(NSString *)sql args:(va_list)arguments
{
NSLogv(sql, arguments);
sql = [[NSString alloc] initWithFormat:sql arguments:arguments];
va_end(arguments);
}
Swift - 在其类中添加
完美工作
protocol CFormatFunction {
class func executeSQLArg(format: String, _ args: CVarArgType...) -> Bool
}
extension MyClassName : CFormatFunction {
class func executeSQLArg(format: String, _ args: CVarArgType...) -> Bool
{
return MyClassName(format, args:getVaList(args))
}
}
MyClassName.executeSQLArg(query, "one","two",3)
[MyClassName executeSQLArg:query, @"one",@"two",@3]
withVaList
,并有些不祥地表示需要“尽量避免”使用getVaList
。(http://swiftdoc.org/v2.1/func/getVaList/#func-getvalist_-cvarargtype) - divergio