2014-06-12 4 views
16

Ich habe Probleme beim Verknüpfen meines Framework mit Code, der dieses Framework nutzt. Insbesondere ist der Linker nicht in der Lage, die Symbole für Erweiterungen für Generics-Strukturen zu finden.Swift Framework enthält keine Symbole aus Erweiterungen für generische Strukturen

Dies ist, was eine der Erweiterungen wie für Optional aussieht:

extension Optional { 
    /// Unwrap the value returning 'defaultValue' if the value is currently nil 
    func or(defaultValue: T) -> T { 
     switch(self) { 
      case .None: 
       return defaultValue 
      case .Some(let value): 
       return value 
     } 
    } 
} 

Diese Methode funktioniert gut auf einem Spielplatz oder in einer App, wenn der Code innerhalb des Hauptteils des App kompiliert wird. Allerdings, wenn ich versuche, dies in einen Rahmen zu kompilieren, Apps (und auch die Tests für das Framework), um die folgenden Linkfehler erzeugen:

Undefined symbols for architecture i386: "__TFSq2orU__fGSqQ__FQQ", referenced from: __TFC18SwiftPlusPlusTests27Optional_SwiftPlusPlusTests13testOrWithNilfS0_FT_T_ in Optional+SwiftPlusPlusTests.o

ähnliche Verfahren wie die folgenden, link fein (Mitteilung ist es nicht auf einem

extension String { 
    /// Returns a string by repeating it 'times' times 
    func repeat(times: Int) -> String { 
     var result = "" 
     for i in 0..times { 
      result += self 
     } 
     return result 
    } 
} 

generic) Es gibt zwei weitere Erweiterungen in meinem Repository auf gitHub: SwiftPlusPlus das auch nicht tun Link (beide auf generische strucs). Sie werden die Fehler reproduzieren, wenn Sie das neueste Commit ausführen, das Framework erstellen und dann versuchen, die Komponententests auszuführen.

Bisher habe ich versucht, "Zeichenfolgen" auf dem ausgegebenen Framework und Zwischendateien auszuführen und ich sehe nicht die Symbole für diese Erweiterungen, aber ich sehe die Symbole für die repeat Methodenerweiterung auf String. Es scheint also nicht einmal so zu sein, dass sie in die Bibliothek kompiliert werden.

Weiß jemand, warum die Symbole nicht im Framework definiert sind?

bearbeiten

  • Here ist ein Link zu meinem Erweiterbar
  • Here ein Link zu der Testdatei, die die Linker-Fehler verursacht beim Versuch, das Testziel
+0

BTW, es generic in Swift statt Vorlage aufgerufen wird –

+0

@BryanChen oh guten Ruf, werde ich meine Frage aktualisieren, dank – drewag

+0

können Sie auf die Klasse verknüpfen definiert in dein Rahmen? und Sie müssen möglicherweise 'YourFramworkModuleName importieren' –

Antwort

9

zu kompilieren I posted on the Apple Developer forums und ein Apple-Mitarbeiter antwortete, dass dies ein bekannter Fehler ist.

It looks like the compiler gets the mangled symbol names of methods in generic extensions wrong when they live in a different framework.

2

Falls Sie für eine temporäre Lösung suchen, können Sie die Erweiterung in einer Klassenmethode wickeln:

// In your framework 
public class OptionalOperator { 
    public class func or<T>(optional:Optional<T>,defaultValue:T) ->T { 
     return optional.or(defaultValue) 
    } 
} 

// Outside the framework 
var maybeText:String? 
let text = OptionalOperator.or(maybeText, defaultValue: "Apple, please fix this") 

Natürlich ist dies nicht ideal ist und den Zweck der Erweiterungen besiegt. Wenn Sie also diese Methode häufig aufrufen möchten, könnten wir overload/define an operator.

// In your framework 
infix operator ||| {} 

public func |||<T>(left:Optional<T>, right:T) -> T { 
    return left.or(right) 
} 

// Outside the framework 
var maybeText:String? 
let text = maybeText ||| "Apple, please fix this" 

In meinem Fall habe ich mehrere Anwendungen den Rahmen verwendet wird, so würde ich die Methode Implementierung innerhalb des Rahmens halten möchte. Allerdings wäre das Überladen eines Operators (oder das Verwenden einer globalen Funktion) umständlich, daher muss ich mit der ersten Option fortfahren, bis der Bug behoben ist.

Hoffe, das hilft.

UPDATE

Komische ist, dass Swift bereits einen Operator für das hat (??).

var maybeText:String? 
let text = maybeText ?? "Nice!" 

Es heißt - Nil Coalescing Operator

Verwandte Themen