2015-05-03 6 views
7

Swift chiusura avrà un ciclo di riferimento forte quando si riferisce ad auto come questo esempio:Forti cicli di riferimento per chiusure?

class Test { 
    var name = "Hello" 

    func doSomething() { 
    {() -> Void in 
     self.name = "otherName" 
    }() 
    } 

} 

Nell'esempio precedente, ho creato un ciclo di riferimento forte quindi devo fissarlo con:

class Test { 
    var name = "Hello" 

    func doSomething() { 
    {[unowned self]() -> Void in 
     self.name = "otherName" 
    }() 
    } 

} 

Domanda: Se mi riferisco a me stesso in una chiusura devo usare sempre unowned self o ci sono casi in cui devo usare weak self?

+0

La chiusura non è fuga (che significa il. la chiusura non è asincrona o non ha un ritardo in modo che possa "rimanere nel campo di applicazione"). Non è necessario utilizzare nessuno dei due. Vedi [escaping vs non-escaping] (https://swiftunboxed.com/lang/closures-escaping-noescape-swift3/). Per un esempio di dove devi usarne uno, vedi [qui] (https://stackoverflow.com/questions/32665326/reference-to-property-in-closure-requires-explicit-self-to-make-capture- seman/40530556 # 40530556) – Honey

risposta

11

Se mi riferisco a me stesso in una chiusura, devo usare sempre il sé non posseduto o ci sono casi in cui devo usare il sé debole?

Nessuno dei due. Nella maggior parte dei casi, fare semplicemente riferimento a self normalmente e non fare nulla con la sua gestione della memoria. Devi solo preoccuparti della gestione della memoria se c'è il pericolo di un ciclo di conservazione e, a meno che tu non memorizzi la chiusura da qualche parte, come una proprietà di sé, non c'è alcun pericolo.

Si può facilmente dimostrare questo con l'aggiunta di un deinit implementazione:

class Test { 
    var name = "Hello" 

    func doSomething() { 
     {() -> Void in 
      self.name = "otherName" 
      }() 
    } 
    deinit { 
     println("bye") 
    } 
} 

Ora fate un esempio di prova e rilasciarlo immediatamente:

func testTest() { 
    let t = Test() 
} 

si vede "bye" nella console, dimostrando che l'istanza è stata rilasciata in buon ordine. Non c'è mai stato alcun "ciclo di riferimento forte" in questo codice. Le tue preoccupazioni sono infondate.

[A proposito, si sta usando la parola "chiusura" errata. Ogni La funzione Swift è una chiusura. Se ci fosse un problema del ciclo di conservazione semplicemente a causa dell'uso della parola self in una chiusura, ogni funzione Swift sarebbe soggetta a questo problema - e chiaramente questo non è il caso. Il luogo in cui weak e unowned auto entra in gioco è in un anonimo funzione - e solo, come ho detto prima, se questa funzione anonima è di per sé trattenuto anche da self]

+0

Per le situazioni in cui si verifica un ciclo di conservazione _can_, e sulla differenza tra 'weak' e' unowned', vedere il mio libro: http://www.apeth.com/swiftBook/ch05.html#_memory_management – matt

+0

Potresti fare un esempio quando usarlo e quando non usarlo per favore? –

+0

Vedi il link che ti ho appena dato! – matt