Objective-cに次のような静的メソッドを持つクラスがあるとします。
+ (NSError *)executeUpdateQuery:(NSString *)query, ...;
それをSwiftから呼び出すにはどうすればよいですか?オートコンプリートはそれを認識せず、コンパイラーは以下に不満があります。
MyClassName.executeUpdateQuery("")
「MyClassName.TypeにexecuteUpdateQueryという名前のメンバーがない」という不満
Variadicメソッドの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 variadic args:
protocol CFormatFunction {
class func executeUpdateQuery(format: String, _ args: CVarArg...) -> NSError?
}
extension MyClassName : CFormatFunction {
class func executeUpdateQuery(format: String, _ args: CVarArg...) -> NSError?
{
return MyClassName.executeUpdateQuery(format, args:getVaList(args))
}
}
MyClassName.executeUpdateQuery("query %d %@ %.2f", 99, "Hello", 3.145)
SwiftはNS_FORMAT_FUNCTION警告を提供しません(-Wformat)
MyClassName.executeUpdateQuery("query %@", 99)
CVArgType
は、C "varargs" APIをSwiftでネイティブに表示するのに役立ちます。 ((Swift Docs)
あなたが持っている場合
+ (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)
注また、この例ではgetVaList
を使用していません。これは、 docs が「最善の回避策である」と言っているためです。 」
必要に応じて、この関数を元のクラスのSwift拡張に追加することもできます。
目的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-クラスに追加するWorks perfect
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))
}
}
使い方
Swift
MyClassName.executeSQLArg(query, "one","two",3)
オブジェティブC
[MyClassName executeSQLArg:query, @"one",@"two",@3]