2014-06-19 8 views
40

Uso Xcode6-beta2, ma ho riscontrato lo stesso problema dalla prima beta pubblica. Il mio sottoclasse Swift di Obj-C UIViewController assomiglia a questo:Accesso alle proprietà di istanza che sono le chiusure

class SomeVC: UIViewController { 
    var c1:() ->() = { 
     println(self) 
    } 

    var c2:() ->() { 
     get { 
      return { println(self) } 
     } 
    } 

    var c3:() ->() { 
     return { println(self) } 
    } 

    override func viewDidAppear(animated: Bool) { 
     super.viewDidAppear(animated) 
     c1() 
     c2() 
     c3() 
    } 
} 

Quando viene visualizzato il VC, vedo le seguenti righe stampate fuori:

(Function) 
<_TtC12SwiftiOSTest6SomeVC: 0x10bf1ed10> 
<_TtC12SwiftiOSTest6SomeVC: 0x10bf1ed10> 

(C2 e C3 differiscono solo nel senso che è non è necessario includere get {...} per una proprietà calcolata se è ottenibile solo.)

Quindi, il primo auto sembra riferirsi al tipo funzione/chiusura stesso, mentre gli altri ' auto fare riferimento al controller della vista (come mi aspetterei). L'unica differenza tra c1 e c2/c3 è che il primo è una proprietà memorizzata, le seconde sono proprietà calcolate, ma mi aspetto ancora che le chiusure ei loro valori acquisiti siano gli stessi, ovvero auto per fare sempre riferimento al classe. Per come stanno le cose ora, non sembra esserci un modo ovvio per la chiusura dello c1 per accedere ai metodi/proprietà della classe che li include.

È qualcosa di documentato da qualche parte (ho letto il libro Swift e non ho trovato nulla), o è solo un bug di un compilatore beta di qualche tipo, che dovrebbe essere archiviato da qualche parte?

risposta

52

Questo sembra interessante. Quindi ho fatto un'indagine. È possibile accedere alle variabili di istanza della classe dalla chiusura come self.instanceVariable. A quel tempo la chiusura sarà cattura il self al suo interno. Così ora lo self si riferisce all'istanza della classe stessa. La tua chiusura dovrebbe essere una proprietà pigra.

A lazy property means that you can refer to self within the default closure, because the lazy property will not be accessed until after initialization has been completed and self is known to exist.

Ti manca @lazy in modo che self è sconosciuto thats chiusura perché la stampa viene inserita come (Function) la mia ipotesi.

class TableViewController: UIViewController { 
var name = "anil" 
// Since swift 2.0 came out @lazy is replaced by lazy 
lazy var c1:() ->() = { 
    println(self) 
    println(self.name) 

} 

var c2:() ->() { 
get { 
    return { println(self) } 
} 
} 

var c3:() ->() { 
return { println(self) } 
} 


    override func viewDidLoad() { 
     super.viewDidLoad() 
     c1() 
     c2() 
     c3() 
     } 
} 

uscita

<_TtC12TableViewApp19TableViewController: 0x10d54e000>
anil
<_TtC12TableViewApp19TableViewController: 0x10d54e000> <_TtC12TableViewApp19TableViewController: 0x10d54e000>


Aggiorna

Assegnazione di chiusura a un'istanza della classe risultati variabili ciclo riferimento forte. Dovresti evitare questo.Swift utilizza lista Capture per quella

If you assign a closure to a property of a class instance, and the closure captures that instance by referring to the instance or its members, you will create a strong reference cycle between the closure and the instance. Swift uses capture lists to break these strong reference cycles. For more information, see Strong Reference Cycles for Closures .

Quindi l'uso corretto di chiusura potrebbe essere

@lazy var c1:() ->() = { 
    [unowned self] in 
    println(self) 
    println(self.name) 

} 

Riferimento: Swift programming guide

Modifica
@lazy è stato cambiato in pigro

+0

Ho provato e ho ottenuto questo errore del compilatore: 'SomeVC ->() -> SomeVC!' non ha un membro chiamato 'nome'. ** Ma **, il tuo codice è diverso dal mio in un altro aspetto: @lazy keywoard/direttiva/qualunque esso sia. Quando aggiungo questo davanti alla definizione di chiusura ** c1 **, funziona, non ho nemmeno bisogno del ** nome ** var. Questo è ancora più confuso, che cosa ha a che fare l'utente pigro con qualcosa qui? – wujek

+0

Controlla la mia risposta aggiornata. specialmente @ pigro –

+0

Quindi questo sembra un bug del compilatore, vero? – wujek

Problemi correlati