clases - inicializadores swift
Modificación de variables de instancia de struct dentro de un cierre de envío en Swift (2)
Está utilizando Swift3 desde que mencionó una dev snapshot
de desarrollo reciente de Swift
. Pruebe a continuación y avíseme si funciona:
public struct ExampleStruct {
let connectQueue = DispatchQueue(label: "connectQueue", attributes: .concurrent)//This creates a concurrent Queue
var test = 10
mutating func example() {
connectQueue.sync {
self.test = 20
}
}
}
Si está interesado en otros tipos de colas, verifique estas:
let serialQueue = DispatchQueue(label: "YOUR_QUEUE", attributes: .serial)
serialQueue.sync {
//
}
Obtenga la mainQueue
forma asíncrona y sincrónica:
DispatchQueue.main.async {
//async operations
}
DispatchQueue.main.sync {
//sync operations
}
Y si te interesan los antecedentes:
DispatchQueue.global(attributes: .qosDefault).async {
//async operations
}
Puede referir esto para nuevas características en Swift3 y para cambios a la versión existente: Migrar a Swift 2.3 o Swift 3 de Swift 2.2
Estoy usando el DEVELOPMENT-SNAPSHOT-2016-06-06-a
versión de Swift. Parece que no puedo evitar este problema, he intentado usar @noescape
en varios lugares, pero todavía tengo el siguiente error:
El cierre no puede capturar implícitamente un parámetro de auto mutación
Para explicar mejor, aquí hay un ejemplo simple:
public struct ExampleStruct {
let connectQueue = dispatch_queue_create("connectQueue", nil)
var test = 10
mutating func example() {
if let connectQueue = self.connectQueue {
dispatch_sync(connectQueue) {
self.test = 20 // error happens here
}
}
}
}
Algo debe haber cambiado en estos binarios Swift que ahora está causando que se rompa mi código anterior. Una solución alternativa que quiero evitar es convertir mi estructura en una clase, lo que ayuda a solucionar el problema. Avíseme si hay otra manera.
No puedo probarlo, porque no estoy usando una compilación con ese error, pero estoy bastante seguro de que al capturar el yo explícitamente puede solucionarlo:
dispatch_sync(connectQueue) { [self] in
self.test = 20
}
EDITAR: Aparentemente no funciona, tal vez puedas probar esto (no muy bien tbh):
var copy = self
dispatch_sync(connectQueue) {
copy.test = 20
}
self = copy
Si desea leer más sobre por qué, esta es la propuesta responsable de Swift .
La nueva API de envío realiza el método de sync
@noreturn
por lo que no necesitaría la captura explícita:
connectQueue.sync {
test = 20
}