2017-10-20 44 views
-1

Je fais un travail de communication sur un fil d'arrière-plan, que je commence comme ceci:Aviser principal thread d'interface utilisateur du fil d'arrière-plan Swift 4

self.thread = Thread(target: self, selector: #selector(threadMain), object: nil) 
    self.thread?.start() 

...

func threadMain() { 
     ... 
    } 

threadMain est invoqué correctement et le traitement roule comme il se doit. La dernière séquence de code sur threadMain est la notification du fil principal par lequel je voulais rappel externe fourni « onComplete », à faire comme ceci:

print("leaving thread") 
    DispatchQueue.main.async { 
     self.onComplete?(CommunicationCallbackParams(errorCode: 
      self.errorCode, commState: self.commState, redirectUrl: self.redirectUrl)) 
    } 

Cependant, le code de la fermeture est jamais appelé. Si je supprime l'enveloppe "DispatchQueue.main.async" cela fonctionne, mais je préviens sur le niveau de thread non-UI. Qu'est-ce qui pourrait mal tourner ici?

Le même principe fonctionne très bien dans l'objectif C ...

+0

Affiche la définition de la propriété 'onComplete'. –

+0

private var onComplete: ((CommunicationCallbackParams) ->())? – decades

+0

Et il est défini à partir du constructeur de la classe requise init (url Theurl: String, onComplete: @escaping ((CommunicationCallbackParams) ->())) { \t \t self.url = Theurl \t \t self.onComplete = onComplete \t \t \t \t super.init() \t \t \t \t self.thread = filetage (cible: self, sélecteur: #selector (threadMain), objet: néant) \t \t self.thread .start (?) \t} – decades

Répondre

0

La chose la plus évidente est que vous appelez self.onComplete avec option Enchaînement. Si onComplete est nul, ce code ne sera pas appelé. Cependant, vous dites qu'il est appelé si vous ne l'enveloppez pas dans un appel à DispatchQueue.main.async.

+0

Exactement. Si je supprime l'enveloppe DispatchQueue.main.async, cela fonctionne ... – decades

0

Oh, trouvé la solution. J'ai appelé la classe de XCTest à l'aide d'un sémaphores afin d'attendre le résultat:

let semaphore = DispatchSemaphore.init(value:0) 
    let _ = Communication(url: "<some url>") { (result) in 
     print("Current thread is main thread: \(Thread.isMainThread)") 
     print(result) 
     semaphore.signal() 
    } 
    semaphore.wait() 

Ce modèle doit sémaphores avoir bloqué la notification. Une fois que je l'ai changé aux attentes, cela a fonctionné très bien.

let exp = expectation(description: "\(#function)\(#line)") 
    let _ = Communication(url: "<some url>") { (result) in 
     print("Current thread is main thread: \(Thread.isMainThread)") 
     print(result) 
     exp.fulfill() 
    } 
    waitForExpectations(timeout: 60, handler: nil)