2016-03-30 14 views
1

Ich habe die folgende MethodeSwift Ambiguos Methoden mit variadische paramameter

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

Das Problem ist, dass ich brauche in Objective C dieses Verfahren zur Verfügung zu stellen, die mit variadische params unmöglich ist. Ich habe versucht, eine andere Methode für Ziel c zu erstellen, wobei params ein Array ist. Aber dann muss ich auch noch eine dritte haben, wenn es keine Params gibt.

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

Aber jetzt rasche beklagt, dass Verfahren t mehrdeutig ist, weil 1. und 3. Methode nur den Schlüssel nehmen.

Wie funktioniert das? Ich weiß, dass ich verschiedene Namen verwenden könnte, aber ich möchte die Dinge konsistent halten.

UPDATE: Ein anderes Problem ist, dass ich String(format:...) nicht richtig einmal in der Funktion aufrufen kann, da params ein Array und keine Gruppe von Parametern ist. Irgendeine nette Lösung?

Antwort

1

Sie können folgendes tun:

@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: []) 
    } 
} 

... von Swift Aufruf:

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

Dieser überbrückt ist wie folgt:

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 

Und kann messaged werden wie folgt :

In Bezug auf die Aktualisierung auf die Frage, gibt es eine Version des formatierten String initialiser die [CVarArgType] statt CVarArgType... nimmt:

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" 

Nur CVarArgType kann nicht in Objective C dargestellt werden, die wirklich die Dinge kompliziert. In der Tat, wenn Sie wirklich String.init(format: String, arguments: [CVarArgType])und bekommen, um es von Objective-C verwenden müssen, dann sehe ich im Moment nicht, wie von AnyObject s CVarArgType s entlang der Linien des folgenden trüben Code zu vermeiden Gießen:

@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) 
    } 
} 

ist Mein Vorschlag Dinge entwöhnen entweder wie String.init(format: String, arguments: [CVarArgType]) oder die Basismethode in Objective C zu implementieren ...

+0

wie in der Frage erwähnt, das Problem tritt auf, wenn Sie die Methode ohne zusätzliche Parameter aus * Swift Rückruf * , z.B 'let foo = C.t (" bar ")'. –

+0

Ja, natürlich, Martin, danke! Ich habe die Antwort geändert ... – milos

+0

Super! Würde das schöner sein :), aber es funktioniert !! –