W Swift jak wywołać metodę z parametrami na głównym wątku GCD?

W mojej aplikacji mam funkcję, która tworzy NSRURLSession i wysyła zapytanie nsurlrequest za pomocą

sesh.dataTaskWithRequest(req, completionHandler: {(data, response, error)

W bloku zakończenia tego zadania, muszę wykonać pewne obliczenia, które dodają interfejs do wywołującego viewcontrollera. I have a func called

func displayQRCode(receiveAddr, withAmountInBTC:amountBTC)

To wykonuje obliczenia dodawania UIImage. Jeśli próbuję uruchomić kod dodawania widoku wewnątrz bloku zakończenia, Xcode rzuca błąd mówiąc, że nie mogę korzystać z silnika układu podczas procesu w tle. Więc znalazłem jakiś kod na tak, że próbuje ustawić metodę w kolejce w głównym wątku:

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)
                        })

Jednak Nie wiem, jak dodać parametry "receiveAddr " i" amountBTC " do tego wywołania funkcji. Jak to zrobić, czy może ktoś zasugerować optymalny sposób na dodanie wywołania metody do kolejki głównej aplikacji?

Author: almel, 2014-07-28

8 answers

Po prostu napisz to w completion handler. nie trzeba używać 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")
}

Również dla wysyłanie po kolejce głównej

DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
  // your code here
}

Zastąp {[5] } klasą delegata

 396
Author: codester,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-20 09:18:14

Wersja Swift 3 & Swift 4:

DispatchQueue.main.async {
    print("Hello")
}

Swift3 i XCode 9.2:

dispatch_async_on_main_queue {
     //Your code
     print("Hello")
 }
 59
Author: DazChong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-17 05:42:01

Swift 2

Używając zamknięć końcowych staje się to:

dispatch_async(dispatch_get_main_queue()) {
    self.tableView.reloadData()
}

Zamykanie końcowe jest szybkim cukrem składniowym, który umożliwia zdefiniowanie zamknięcia poza zakresem parametru funkcji. Aby uzyskać więcej informacji, zobacz końcowe zamknięcia w podręczniku języka programowania Swift 2.2.

W przypadku dispatch_async API jest func dispatch_async(queue: dispatch_queue_t, _ block: dispatch_block_t) Ponieważ dispatch_block_t jest aliasem typu dla () -> Void - zamknięcia, które otrzymuje 0 parametrów i nie ma zwracanej wartości, a blok jest ostatnim parametr funkcji możemy zdefiniować zamknięcie w zewnętrznym zakresie dispatch_async.

 14
Author: Maxim Veksler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-25 19:06:10

Oto ładniejsza (IMO) składnia stylu Swifty/Cocoa, aby osiągnąć ten sam wynik co pozostałe odpowiedzi:

NSOperationQueue.mainQueue().addOperationWithBlock({
    // Your code here
})

Lub możesz pobrać popularną Async Swift library dla jeszcze mniej kodu i większej funkcjonalności:

Async.main {
    // Your code here
}
 5
Author: pejalo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-13 06:12:02

Właściwym sposobem na to jest użycie dispatch_async w main_queue, tak jak zrobiłem w poniższym kodzie

dispatch_async(dispatch_get_main_queue(), {
                        (self.delegate as TBGQRCodeViewController).displayQRCode(receiveAddr, withAmountInBTC:amountBTC)
                        })
 3
Author: almel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-07 17:54:16

Oto mała funkcja globalna, którą możesz dodać dla ładniejszej składni:

func dispatch_on_main(block: dispatch_block_t) {
    dispatch_async(dispatch_get_main_queue(), block)
}

I użycie

dispatch_on_main {
    // Do some UI stuff
}
 2
Author: Mateusz Grzegorzek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-26 11:58:23

Nie zapomnij osłabić siebie, jeśli używasz jaźni wewnątrz zamknięcia.

dispatch_async(dispatch_get_main_queue(),{ [weak self] () -> () in
            if let strongSelf = self {
                self?.doSomething()
            }
        })
 1
Author: villy393,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-15 15:25:59

Reload collectionView na głównym wątku

 DispatchQueue.main.async {
                self.collectionView.reloadData()
            }
 -1
Author: Sanjay Mali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-10 11:21:57