2014-11-19 6 views
9

In HMSegmentedControl, vorrei impostare lo segmentedControl.indexChangeBlock su un metodo di istanza per gestire l'azione. L'esempio ufficiale è: https://github.com/HeshamMegid/HMSegmentedControl/blob/master/HMSegmentedControlExample/HMSegmentedControlExample/ViewController.m (riga 63 ~ 68), ma questo è Objective-C.Come impostare un riferimento debole a una chiusura/funzione in Swift?

In Swift, le funzioni sono cittadini di prima classe. Quindi voglio impostare un metodo di istanza per questa proprietà di blocco.
Ma il mio codice porterebbe a un riferimento circolare, sembra che dovrei definire un riferimento debole:

class ExampleVC: UIViewController { 
    var segmentedControlIndex: Int = 0 

    override func viewDidLoad() { 
     let segmentedControl3 = HMSegmentedControl(sectionImages: ... , sectionSelectedImages: ...) 
     segmentedControl3.frame = ... 
     segmentedControl3.indexChangeBlock = someInstanceMethod 
    } 

    func someInstanceMethod(index: Int) { 
     segmentedControlIndex = index 
    } 
} 

Tuttavia, non posso definire un debole riferimento ad un tipo non-class. Cosa posso fare? è legale fare questo?

+0

possibile duplicato del [Fare sé debole nei metodi a Swift ] (http://stackoverflow.com/questions/25613783/make-self-weak-in-methods-in-swift) – user102008

risposta

4

Invece di definire un riferimento debole alla chiusura, è necessario utilizzare "Capture List" nella chiusura.

segmentedControl3.indexChangeBlock = { [unowned self] in self.someInstanceMethod($0) } 

Per quanto ne so, questo è l'unico modo per evitare cicli di riferimento intensi.

+3

'[self debole]' interromperà il ciclo di riferimento ed è generalmente meno soggetto a rotture quando il codice diventa refactored o vista le gerarchie sono riorganizzate. –

12

[unowned self] è pericoloso. Quello che fa è dire al runtime "Supponiamo che l'auto non sia stato rilasciato, non preoccuparti di controllare". Se nel frattempo viene rilasciato self, l'applicazione sarà SEGFAULT.

In questo caso, { [weak self] in self?.someInstanceMethod($0) } interromperà il ciclo di riferimento e si trasformerà in no-op se viene rilasciato self.

[weak self] è sempre sicuro, mentre [unowned self] può introdurre blocca app se si modifica altre aree del codice (come gerarchia della vista, per esempio) ...

+0

HMSegmentedControl appartiene all'EsempioVC, quindi non avrai mai se stesso di essere nullo. E come Apple dice: usa unowned ogni volta che è possibile. – Dam

+1

Unowned è ancora fondamentalmente pericoloso. So che è bene seguire ciò che Apple consiglia, e questo è probabilmente per motivi di prestazioni, ma io sostengo la mia raccomandazione, per i motivi che ho delineato. –

+1

Sono d'accordo con te, debole sarà sempre al sicuro. Il punto era solo non posseduto non è solo supporre che non è un rilascio, è più, come lo sviluppatore, dico che non sarà mai nulla. Ma sono anche d'accordo con te, preferisco essere sicuro al 100% che lasciare che qualcuno dica che è sicuro, salta. – Dam