programing

Swift 3, 4, 5에서 GCD 뒤에 dispatch_를 쓰는 방법은 무엇입니까?

javajsp 2023. 4. 14. 21:12

Swift 3, 4, 5에서 GCD 뒤에 dispatch_를 쓰는 방법은 무엇입니까?

에서는 Swift 2를 할 수 .dispatch_after그랜드 센트럴 디스패치를 사용하여 액션을 지연시키려면:

var dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC))) 
dispatch_after(dispatchTime, dispatch_get_main_queue(), { 
    // your function here 
})

그러나 이것은 Swift 3 이후로 더 이상 컴파일되지 않는 것 같다.이것을 현대 Swift로 쓸 때 선호하는 방법은 무엇입니까?

구문은 다음과 같습니다.

// to run something in 0.1 seconds

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

을 참고해 주세요.secondsDouble(nsec을 추가하는 것에 익숙해져 있기 때문에) 혼란의 원인이 되고 있는 것 같습니다.는 '초수 추가'입니다.Double이 통할 수 것은 '하다'가 있기 때문입니다deadline는 입니다.DispatchTime그 에는 리고대 and and and and가 있다.+「」를 .Double를 「」에 해 주세요.DispatchTime:

public func +(time: DispatchTime, seconds: Double) -> DispatchTime

단, 또는 nsec의 를 「nsec」, 「msec」, 「nsec」에하는 경우는, 「nsec」로 .DispatchTime , 을도 있습니다.DispatchTimeInterval a까지DispatchTime 하면 , 이렇게 할 수 있다, 할 수 있다, 할 수 있다, 할 수 있다, 할수 있다, 할 수 있다, 할 수 있다, 할 수 있다, 할 수 있다, 할 수 있다, 할 수 있다, 할 수 있다.

DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) {
    // 500 msec, i.e. 0.5 seconds
    …
}

DispatchQueue.main.asyncAfter(deadline: .now() + .microseconds(1_000_000)) {
    // 1m microseconds, i.e. 1 second
    …
}

DispatchQueue.main.asyncAfter(deadline: .now() + .nanoseconds(1_500_000_000)) {
    // 1.5b nanoseconds, i.e. 1.5 seconds
    …
}

하는 것은, 이 입니다.+DispatchTime를 누릅니다

public func +(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime

파견된 작업을 취소하는 방법에 대해 물었다. 위해서는, 「」를 합니다.DispatchWorkItem, 뷰 , 그 태스크의 「」, 「5」는 「」, 「5」로 설정되어 있습니다.deinit

class ViewController: UIViewController {

    private var item: DispatchWorkItem?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        item = DispatchWorkItem { [weak self] in
            self?.doSomething()
            self?.item = nil
        }
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 5, execute: item!)
    }

    deinit {
        item?.cancel()
    }
    
    func doSomething() { … }
}

「 」의 .[weak self] DispatchWorkItem이는 강한 참조 사이클을 피하기 위해 필수적입니다.또한 이 작업은 사전 취소가 아니라 아직 시작되지 않은 작업만 중지합니다., 이미 되었을 때 시작되었을 cancel()수동으로 한) 됩니다.isCancelled」를 참조해 주세요.


신속한 동시성

질문은 이었는데, GCD는 GCD에 대한 GCD에 대한 것입니다.dispatch_after. "" " " " " " " " "asyncAfter이에 Swift 그 API인 Swift에서 에 대한 .async-awaitiOS 16 및 MacOS 13에서는 다음을 권장합니다.

try await Task.sleep(for: .seconds(2))        // 2 seconds
…

또는

try await Task.sleep(for: .milliseconds(200)) // 0.2 seconds
…

또는 iOS 13 및 macOS 10.15를 지원해야 하는 경우 대신 을 사용합니다.

하려면 , 「」를 .Task:

class ViewController: UIViewController {

    private var task: Task<Void, Error>?

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        task = Task {
            try await Task.sleep(for: .seconds(5))
            await doSomething()
        }
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)

        task?.cancel()
    }

    func doSomething() async { … }
}

또는 Swift에서UI를 사용하면 "보기가 사라진 후 작업이 완료되기 전에 작업이 자동으로 취소되는" 뷰 수식자를 사용할 수 있습니다.저장도 필요 없습니다.Task나중에 수동으로 취소할 수 있습니다.

에, 임의의 「Swift」, 「Swift」를 을 인식할 .sleep이 함수는 현재 스레드를 차단하기 때문에 신중하게 피해야 하는 안티 패턴이었습니다.이는 메인 스레드에서 수행했을 때 심각한 오류였지만, GCD 워커의 스레드 풀이 너무 한정되어 있기 때문에 백그라운드 스레드에서 사용했을 때도 문제가 있었습니다.그러나 새로운 기능은 현재의 스레드를 차단하지 않으므로 어떤 배우(주인공 포함)로부터도 안전하게 사용할 수 있습니다.

Swift 4:

DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {
   // Code
}

★★★★★★★★★★★★★★★..seconds(Int),.microseconds(Int) ★★★★★★★★★★★★★★★★★」.nanoseconds(Int)사용할 수도 있습니다.

지연함수만 원하는 경우

Swift 4 & 5

func delay(interval: TimeInterval, closure: @escaping () -> Void) {
     DispatchQueue.main.asyncAfter(deadline: .now() + interval) {
          closure()
     }
}

다음과 같이 사용할 수 있습니다.

delay(interval: 1) { 
    print("Hi!")
}

Swift 3 출시 후 @escaping도 추가해야 합니다.

func delay(_ delay: Double, closure: @escaping () -> ()) {
  DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
    closure()
  }
}

수용된 답변의 약간 다른 맛입니다.

스위프트 4

DispatchQueue.main.asyncAfter(deadline: .now() + 0.1 + .milliseconds(500) + 
.microseconds(500) + .nanoseconds(1000)) {
                print("Delayed by 0.1 second + 500 milliseconds + 500 microseconds + 
                      1000 nanoseconds)")
 }

스위프트 4

Dispatch 하여 Dispatch Queue를 할 수 .DispatchQueue는 After의 내부 기능을 합니다.

extension DispatchQueue {
   static func delay(_ delay: DispatchTimeInterval, closure: @escaping () -> ()) {
      DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: closure)
   }
}

및 사용

DispatchQueue.delay(.milliseconds(10)) {
   print("task to be done")
}

DispatchQueue.main.after(when: DispatchTime, execute: () -> Void)

Xcode 툴을 사용하여 Swift 3으로 변환할 것을 강력히 권장합니다([Edit]> [ Convert ]> [ To Current Swift Syntax ] ) 。나 이거 잡혔어

Swift 5 이상

DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: {
   // code to execute                 
})

비메인 스레드에서 실행되는 답변이 없습니다. 그러니 2센트를 더하십시오.

메인 큐(메인 스레드)

let mainQueue = DispatchQueue.main
let deadline = DispatchTime.now() + .seconds(10)
mainQueue.asyncAfter(deadline: deadline) {
    // ...
}

또는

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .seconds(10)) { 
    // ...
}

글로벌 큐(지정된QOS에 기반한 메인스레드 이외).

let backgroundQueue = DispatchQueue.global()
let deadline = DispatchTime.now() + .milliseconds(100)
backgroundQueue.asyncAfter(deadline: deadline, qos: .background) { 
    // ...
}

또는

DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + .milliseconds(100), qos: .background) {
    // ...
}

언급URL : https://stackoverflow.com/questions/37801436/how-do-i-write-dispatch-after-gcd-in-swift-3-4-and-5