2014-06-12 5 views
16

Ho problemi a collegare il mio framework con il codice che sfrutta tale framework. In particolare, il linker non è in grado di trovare i simboli per le estensioni per le strutture generiche.Swift Framework non include i simboli dalle estensioni alle strutture generiche

Questo è ciò che una delle estensioni assomiglia per facoltativo:

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

Questo metodo funziona alla grande in un parco giochi o in un app se il codice viene compilato all'interno della parte principale della app. Tuttavia, quando provo a compilare questo in un quadro, applicazioni (e anche i test per il quadro) producono il seguente errore di linker:

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

metodi simili come quello seguente, collegano bene (avviso, non è su un generico)

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

ci sono altre due estensioni all'interno della mia repository su GitHub: SwiftPlusPlus che anche non collegare (entrambi su strucs generici). Si riprodurranno gli errori se si estrae l'ultimo commit, si costruisce il framework e quindi si tenta di eseguire i test unitari.

Finora ho provato a eseguire "stringhe" sul framework emesso e sui file intermedi e non vedo i simboli per queste estensioni ma vedo i simboli per l'estensione del metodo repeat su String. Quindi non sembra nemmeno che li stia compilando nella libreria.

Qualcuno sa perché i simboli non sono definiti nel framework?

Modifica

  • Here è un link al mio estensione opzionale
  • Here è un collegamento al file di test che causa l'errore di linker quando si cerca di compilare il target di test
+0

proposito, si parla di generici al posto di modello nella Swift –

+0

@BryanChen oh buona chiamata, aggiornerò la mia domanda, grazie – drewag

+0

è possibile collegare alla classe definita in la tua struttura? e potresti aver bisogno di 'import YourFramworkModuleName' –

risposta

9

I posted on the Apple Developer forums e un dipendente Apple hanno risposto che si tratta di un bug noto.

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

2

Nel caso in cui siete alla ricerca di una soluzione temporanea, si può avvolgere l'estensione in un metodo di classe:

// 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") 

Naturalmente, questo non è l'ideale e sconfigge lo scopo di estensioni. Quindi se pianifichi di chiamare questo metodo frequentemente, potremmo 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" 

Nel mio caso, ho più applicazioni che utilizzano il framework, quindi mi piacerebbe mantenere l'implementazione del metodo all'interno del framework. Tuttavia, sovraccaricare un operatore (o semplicemente usare una funzione globale) sarebbe imbarazzante, quindi devo andare con la prima opzione fino a che quel bug non viene corretto.

Spero che questo aiuti.

UPDATE

cosa divertente è che Swift ha già un operatore per questo (??).

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

Si chiama - Nil coalescenza Operatore

Problemi correlati