parameters - programacion - tipos de datos en swift
En Swift, ¿cómo llamar al método con parámetros en el hilo principal de GCD? (7)
En mi aplicación tengo una función que hace una sesión NSRURLSession y envía una solicitud NSURL usando
sesh.dataTaskWithRequest(req, completionHandler: {(data, response, error)
En el bloque de finalización para esta tarea, necesito hacer algunos cálculos que agreguen un UIImage al controlador de vista llamante. Tengo un func llamado
func displayQRCode(receiveAddr, withAmountInBTC:amountBTC)
eso hace el cálculo de adición de UIImage. Si trato de ejecutar el código de adición de vista dentro del bloque de finalización, Xcode arroja un error que dice que no puedo usar el motor de diseño mientras estoy en un proceso en segundo plano. Así que encontré un código en SO que intenta poner en cola un método en el hilo principal:
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(0.0 * Double(NSEC_PER_MSEC)))
dispatch_after(time, dispatch_get_main_queue(), {
let returned = UIApplication.sharedApplication().sendAction("displayQRCode:", to: self.delegate, from: self, forEvent: nil)
})
Sin embargo, no sé cómo agregar los parámetros "receiveAddr" y "amountBTC" a esta llamada de función. ¿Cómo podría hacerlo, o alguien puede sugerir una forma óptima para agregar una llamada a método a la cola principal de la aplicación?
Aquí está la sintaxis de estilo Swifty / Cocoa más agradable (IMO) para lograr el mismo resultado que las otras respuestas:
NSOperationQueue.mainQueue().addOperationWithBlock({
// Your code here
})
O bien, puede obtener la popular biblioteca Async Swift para obtener incluso menos código y más funcionalidades:
Async.main {
// Your code here
}
Aquí hay una pequeña y agradable función global que puede agregar para una sintaxis más agradable:
func dispatch_on_main(block: dispatch_block_t) {
dispatch_async(dispatch_get_main_queue(), block)
}
Y uso
dispatch_on_main {
// Do some UI stuff
}
La forma correcta de hacerlo es usar dispatch_async en main_queue, como hice en el siguiente código
dispatch_async(dispatch_get_main_queue(), {
(self.delegate as TBGQRCodeViewController).displayQRCode(receiveAddr, withAmountInBTC:amountBTC)
})
No te olvides de debilitarte si estás usando uno mismo dentro del cierre.
dispatch_async(dispatch_get_main_queue(),{ [weak self] () -> () in
if let strongSelf = self {
self?.doSomething()
}
})
Simplemente escriba esto en el completion handler
No necesita usar dispatch_after
dispatch_async(dispatch_get_main_queue(), {
let delegateObj = UIApplication.sharedApplication().delegate as YourAppDelegateClass
delegateObj.addUIImage("yourstring")
})
Swift 3:
DispatchQueue.main.async {
let delegateObj = UIApplication.sharedApplication().delegate as YourAppDelegateClass
delegateObj.addUIImage("yourstring")
}
También para el envío después de la cola principal
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
// your code here
}
Reemplace YourAppDelegateClass
con su clase de delegado
Swift 3 y Swift 4 versión:
DispatchQueue.main.async {
print("Hello")
}
Swift 2
Usando Trailing Closures esto se convierte en:
dispatch_async(dispatch_get_main_queue()) {
self.tableView.reloadData()
}
Trailing Closures es un azúcar sintáctico Swift que permite definir el cierre fuera del alcance del parámetro de la función. Para obtener más información, consulte los cierres finales en la Guía de lenguaje de programación de Swift 2.2.
En el caso dispatch_async la API es func dispatch_async(queue: dispatch_queue_t, _ block: dispatch_block_t)
ya que dispatch_block_t
es tipo alias para () -> Void
- Un cierre que recibe 0 parámetros y no tiene un valor de retorno, y el bloque es el último parámetro de la función podemos definir el cierre en el ámbito externo de dispatch_async
.