2014-06-07 14 views
42

Ho incontrato questo problema alcune volte mentre portavo il codice Objective-C a Swift. Dire che ho il seguente codice:Utilizzo di dispatch_async con auto

dispatch_async(dispatch_get_main_queue()) { 
    self.hostViewController?.view.addSubview(self.commandField) 
} 

Questo si tradurrà in un errore, sottolineando l'intera dispatch_async chiamata, che offre:

Suppongo che questo è un errore che non è stata ancora attuata correttamente perché se inserisco la chiamata addSubview all'esterno del blocco dispatch_async, il progetto si integra correttamente. Inizialmente pensavo che potesse avere qualcosa a che fare con l'acquisizione di self nel blocco. Tuttavia, l'inserimento di [unowned self] in produce lo stesso errore, così come lo è [weak self] in (dopo che sono stati inseriti gli operatori di scartamento appropriati !).

Come posso ottenere i blocchi dispatch_async per funzionare in Swift che devono acquisire self?

risposta

65

Si dovrebbe condizionare lo scorporo questa azione sulla non la nullità, non prova per esso dopo aver già avviato esso:

if let hostView = self.hostViewController?.view { 
    DispatchQueue.main.async { 
     hostView.addSubview(self.commandField) 
    } 
} else { 
    // handle nil hostView 
} 

non si dovrebbe mai scartare un fuori facoltativa di un if let, o testarlo primo. Fare questo dovrebbe anche risolvere il tuo problema di auto debole.

+0

Ah che funziona, grazie! Quindi il compilatore si lamenta di non poter scartare in modo deterministico 'hostController?' All'interno del blocco? O c'è qualcos'altro che succede qui? – Ephemera

+5

È perché l'espressione 'self.hostViewController? .view' restituisce un oggetto di tipo' NSView? ', * Not *' NSView'. Le catene opzionali devono sempre essere controllate e il risultato deve essere lasciato in sospeso o forzato. – iluvcapra

12

La sintassi dispatch_async è cambiato con Swift 3:

DispatchQueue.main.async { 
    hostView.addSubview(self.commandField) 
} 
Problemi correlati