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?
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
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")
}
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
.
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
}
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)
})
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
}
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()
}
})
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()
}
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