Swift에서 GCD 메인 스레드에 매개 변수를 사용하여 메서드를 호출하는 방법은 무엇입니까?
내 앱에는 NSRLSession을 만들고 NSURLRequest를 전송하는 기능이 있습니다.
sesh.dataTaskWithRequest(req, completionHandler: {(data, response, error)
이 태스크의 완료 블록에서는, 발신측 뷰 컨트롤러에 UIImage를 추가하는 계산을 실시할 필요가 있습니다.내 펑크가 있는데
func displayQRCode(receiveAddr, withAmountInBTC:amountBTC)
UIIMage 가산 연산을 합니다.완료 블록 내에서 뷰 추가 코드를 실행하려고 하면 백그라운드 처리 중에 레이아웃 엔진을 사용할 수 없다는 오류가 발생합니다.SO에서 메인 스레드에서 메서드를 큐잉하려고 하는 코드를 찾았습니다.
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)
})
단, "receiveAddr" 및 "amountB" 파라미터를 추가하는 방법을 모릅니다.TC"를 선택합니다.이 작업을 어떻게 해야 합니까, 아니면 응용 프로그램의 메인 큐에 메서드 호출을 추가하는 최적의 방법을 제안할 수 있습니까?
최신 버전의 Swift 사용DispatchQueue.main.async
메인 스레드에 디스패치하려면:
DispatchQueue.main.async {
// your code here
}
메인 큐에서 다음 명령을 사용합니다.
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
// your code here
}
이전 버전의 Swift 사용:
dispatch_async(dispatch_get_main_queue(), {
let delegateObj = UIApplication.sharedApplication().delegate as YourAppDelegateClass
delegateObj.addUIImage("yourstring")
})
Swift 3+ 및 Swift 4 버전:
DispatchQueue.main.async {
print("Hello")
}
Swift 3 및 Xcode 9.2:
dispatch_async_on_main_queue {
print("Hello")
}
스위프트 2
Trailing Closures를 사용하면 다음과 같이 됩니다.
dispatch_async(dispatch_get_main_queue()) {
self.tableView.reloadData()
}
Trailing Closures(후행 폐쇄)는 Swift 구문설탕으로, 함수 파라미터 스코프 외부에 폐쇄를 정의할 수 있습니다.자세한 내용은 Swift 2.2 Programming Language Guide의 Trailing Closures를 참조하십시오.
dispatch_async의 경우 API는func dispatch_async(queue: dispatch_queue_t, _ block: dispatch_block_t)
부터dispatch_block_t
의 타입 에일리어스입니다.() -> Void
- 0개의 파라미터를 수신하고 반환값을 가지지 않는 폐쇄이며, 블록은 함수의 마지막 파라미터로서 외부 스코프에서 폐쇄를 정의할 수 있습니다.dispatch_async
.
컬렉션 다시 로드기본 스레드 보기
DispatchQueue.main.async {
self.collectionView.reloadData()
}
다음은 다른 답변과 동일한 결과를 얻기 위한 더 좋은(IMO) Swifty/Cocoa 스타일의 구문입니다.
NSOperationQueue.mainQueue().addOperationWithBlock({
// Your code here
})
또는 일반적인 Async Swift 라이브러리를 사용하여 코드를 줄이고 기능을 향상시킬 수 있습니다.
Async.main {
// Your code here
}
적절한 방법은 다음 코드와 같이 main_queue에서 dispatch_async를 사용하는 것입니다.
dispatch_async(dispatch_get_main_queue(), {
(self.delegate as TBGQRCodeViewController).displayQRCode(receiveAddr, withAmountInBTC:amountBTC)
})
를 사용하여 메인 스레드로 전환할 수 있습니다.
DispatchQueue.main.async {
// UI Code Goes Here
}
당신은 또한 다음 POP에 의해 my writing your custom protocol을 더 재사용 가능하고 읽을 수 있는 코드를 쓸 수 있습니다.
protocol MainThreadRunAble : AnyObject {}
확장을 사용한 프로토콜 구현
extension MainThreadRunAble {
func runOnMain(code : @escaping()->()) {
DispatchQueue.main.async {
code()
}
}
func runOnMain(withDelay delay : Float ,code : @escaping()->()){
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
code()
}
}}
클래스를 메인 스레드에서 실행할 프로토콜에 준거합니다.
class YourClass : BaseClass,MainThreadRunAble{}
그 후, 요구에 따라서, 어느쪽인가를 호출합니다.
runOnMain {
//update on main
}
runOnMain(withDelay: 1) {
//update on main
}
아키텍처 중 하나를 사용하고 있는 경우 뷰 컨트롤러만이 메인 스레드에서 실행할 수 있는 이 코드에 액세스할 수 있습니다.그 후 확장 기능을 구현합니다.
extension UIViewController {
func runOnMain(code : @escaping()->()) {
DispatchQueue.main.async {
code()
}
}
func runOnMain(withDelay delay : Float ,code : @escaping()->()){
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
code()
}
}}
다음은 더 나은 구문을 위해 추가할 수 있는 작은 글로벌 함수입니다.
func dispatch_on_main(block: dispatch_block_t) {
dispatch_async(dispatch_get_main_queue(), block)
}
사용방법
dispatch_on_main {
// Do some UI stuff
}
//Perform some task and update UI immediately.
DispatchQueue.global(qos: .userInitiated).async {
// Call your function here
DispatchQueue.main.async {
// Update UI
self.tableView.reloadData()
}
}
//To call or execute function after some time
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
//Here call your function
}
//If you want to do changes in UI use this
DispatchQueue.main.async(execute: {
//Update UI
self.tableView.reloadData()
})
폐쇄의 내부에서 자신을 이용한다면 자신을 약하게 만드는 것을 잊지 마세요.
dispatch_async(dispatch_get_main_queue(),{ [weak self] () -> () in
if let strongSelf = self {
self?.doSomething()
}
})
최신 Swift 코드(Swift 5.5+ 및 iOS 13+)의 경우, Apple은 보다 깨끗하고 성능적이며 안전한 코드를 위해 GCD가 아닌 주요 스레드 작업을 주연 배우에게 제안합니다.
여기에서는 배우를 이용하여 본선에 파견하는 4가지 방법을 자세히 설명했습니다.
은 문제의 입니다.@MainActor
속성 래퍼
@MainActor func callFunctionOnMainThread(paramOne: Int, paramTwo: String) {
// We can now access parameters on the main thread
}
이치노 async/await
:
await callFunctionOnMainThread(paramOne: 2, paramTwo: "Two")
언급URL : https://stackoverflow.com/questions/24985716/in-swift-how-to-call-method-with-parameters-on-gcd-main-thread
'sourcecode' 카테고리의 다른 글
Linux Bash에서 어레이에 LS를 할당하려면 어떻게 해야 합니까? (0) | 2023.04.13 |
---|---|
iOS 8.0 이전 버전에서는 자동 우선 레이아웃 폭을 사용할 수 없습니다. (0) | 2023.04.13 |
GitHub "치명적: 원격 원본이 이미 있습니다" (0) | 2023.04.13 |
Swift에서 열거값 이름을 얻는 방법은 무엇입니까? (0) | 2023.04.13 |
Oracle 10g에서 테이블 열의 이름을 변경하는 방법 (0) | 2023.04.13 |