Swift se bloquea cuando se actualiza el valor publicado dentro de un hilo de forma sincrónica en iOS 13.
Tengo varios pasos que deben procesarse de forma sincrónica. Y el valor resultante del proceso es consumido por la vista. Funciona en iOS 14, pero se bloquea en iOS 13. Utilizo Combine para publicar un evento y actualizar el valor almacenado dentro del modelo de vista.
Este es el PublisherManager:
final class PublisherManager {
static let shared = PublisherManager()
private var cancellable = Set<anycancellable>()
func mainPublisher() -> AnyPublisher<maininput, never=""> {
mainSubject
.eraseToAnyPublisher()
}
let mainSubject = PassthroughSubject<maininput, never="">()
enum MainInput {
case updateValue()
}
}
Este es el modelo de vista:
final class ViewModel: ObservableObject {
@Published var status: Status = .checking
init() {
setObserver()
start()
}
private func setObserver() {
PublisherManager.shared.mainPublisher()
.receive(on: RunLoop.main)
.sink { [weak self] action in
guard let self = self else { return }
switch action {
case .updateValue:
self.updateValue()
}
}.store(in: &cancellable)
}
func start() {
let dispatchGroup = DispatchGroup()
let dispatchSemaphore = DispatchSemaphore(value: 1)
dispatchGroup.enter()
dispatchQueue.asyncAfter(deadline: DispatchTime.now() + 1) {
dispatchSemaphore.wait()
self.getValues { //--> Un proceso para llamar a una API
PublisherManager.shared.pushNotificationTroubleshooterSubject.send(.updateValue())
dispatchSemaphore.signal()
dispatchGroup.leave()
}
}
dispatchGroup.notify(queue: .main) {
// Notificación
}
}
private func updateValue() {
status = .active
}
}
Cuando lo ejecuto, obtengo un EXCBADACCESS en AppDelegate pero no muestra ningún error en el depurador. Si comento el código status = .active
, no se bloquea.
¿Qué estoy haciendo mal y cómo puedo solucionar el problema?</maininput,></maininput,>
davy.ai
El problema puede estar relacionado con el acceso a la propiedad
status
desde diferentes hilos, ya que es probable que el métodogetValues
sea llamado en un hilo de fondo. Una posible solución es utilizarDispatchQueue.main.async
para actualizar la propiedadstatus
en el hilo principal:Otro enfoque es utilizar una cola en serie para garantizar que el acceso a la propiedad
status
esté sincronizado entre hilos:En cualquier caso, asegúrate de actualizar la propiedad
status
solo en el hilo principal para evitar problemas de seguridad de hilos.