Swift 3에서 디스패치 큐를 생성하는 방법


403

Swift 2에서는 다음 코드를 사용하여 대기열을 만들 수있었습니다.

let concurrentQueue = dispatch_queue_create("com.swift3.imageQueue", DISPATCH_QUEUE_CONCURRENT)

그러나 이것은 Swift 3에서 컴파일되지 않습니다.

Swift 3에서 이것을 작성하는 선호되는 방법은 무엇입니까?



Swift 4에는 직렬 대기열을 만들기위한 3 개의 추가 매개 변수가 있습니다. 그것들을 사용하여 직렬 대기열을 만드는 방법은 무엇입니까? DispatchQueue.init (label :, qos :, 속성 :, autoreleaseFrequency :, target
:)

@ nr5 대기열은 기본적으로 직렬이므로 DispatchQueue(label: "your-label")직렬 대기열 에만 사용하면 충분합니다 . 추가 매개 변수에는 모두 기본값이 있습니다.
jbg

답변:


1131

동시 큐 작성

let concurrentQueue = DispatchQueue(label: "queuename", attributes: .concurrent)
concurrentQueue.sync {

}  

시리얼 큐 생성

let serialQueue = DispatchQueue(label: "queuename")
serialQueue.sync { 

}

기본 대기열을 비동기 적으로 가져 오기

DispatchQueue.main.async {

}

메인 큐를 동 기적으로 가져 오기

DispatchQueue.main.sync {

}

백그라운드 스레드 중 하나를 얻으려면

DispatchQueue.global(qos: .background).async {

}

Xcode 8.2 베타 2 :

백그라운드 스레드 중 하나를 얻으려면

DispatchQueue.global(qos: .default).async {

}

DispatchQueue.global().async {
    // qos' default value is ´DispatchQoS.QoSClass.default`
}

이 대기열 사용에 대해 배우려면이 답변을 참조하십시오.


3
attributes: .serial직렬 대기열을 만들 때 실제로 생략 할 수 있습니다 let serialQueue = DispatchQueue(label: "queuename").
kean

15
Xcode 8 베타 4에는 .serial 옵션이 없으므로 속성에서 .concurrent를 생략하여 직렬 큐를 만들어야합니다.
Oleg Sherman

dispatch_queue_t backgroundQueue를 수행 할 때 'OS_dispatch_queue * _Nonnull'유형의 rvalue로 '__strong dispatch_queue_t'(일명 'NSObject <OS_dispatch_queue> * __ strong') 변수를 초기화 할 수 없습니다. = [SwiftClass 대기열]; 즉, 신속한 DispatchQueue에서의 정적 변수
ideerge

Swift 3.0에서 DispatchQueue.main.asynchronously (DispatchQueue.main) {self.mapView.add (self.mapPolyline)} DispatchQueue.global (). asynchronously (DispatchQueue.main) {self.mapView.add (self .mapPolyline)} 그러나 모두 나타낸다 "형 dispathQuoue 값 비동기 어떤 부재가 없다"와 같은 에러
Abirami 발라

1
OP의 코드에서 애플은 왜 "com.swift3.imageQueue" 사용에 초점을 맞 춥니 다 . 라벨에는 3 개의 부품이 있습니다. 왜 그런 겁니까? 각 부분의 의미는 무엇입니까? 나는 형식을 얻지 못한다
Honey

55

> = Swift 3 에서 컴파일합니다 . 이 예에는 필요한 대부분의 구문이 포함되어 있습니다.

QoS-새로운 서비스 품질 구문

weak self -유지주기 중단

자아를 구할 수 없으면 아무 것도하지 마십시오

async global utility queue-네트워크 쿼리의 경우 결과를 기다리지 않고 동시 큐이며 블록이 시작될 때 (대개) 기다리지 않습니다. 동시 큐에 대한 예외는 해당 태스크 한계에 도달했을 때 큐가 일시적으로 직렬 큐로 바뀌고 해당 큐의 일부 이전 태스크가 완료 될 때까지 대기합니다.

async main queue-UI를 터치하기 위해 블록은 결과를 기다리지 않지만 시작시 슬롯을 기다립니다. 기본 대기열은 직렬 대기열입니다.

물론, 이것에 약간의 오류 검사를 추가해야합니다 ...

DispatchQueue.global(qos: .utility).async { [weak self] () -> Void in

    guard let strongSelf = self else { return }

    strongSelf.flickrPhoto.loadLargeImage { loadedFlickrPhoto, error in

        if error != nil {
            print("error:\(error)")
        } else {
            DispatchQueue.main.async { () -> Void in
                activityIndicator.removeFromSuperview()
                strongSelf.imageView.image = strongSelf.flickrPhoto.largeImage
            }
        }
    }
}

6
스위프트 3 코딩 할 때, 응축 :-) 이전 코드의 30 %를 삭제 익숙해
t1ser

[약한 자기] 예를 주셔서 감사합니다!
imike

1
그것은 더 나은에있어 guardself없는 nil이 있다면 코드 중 어느 것도 실행되지 않습니다 그래서, 상단에 nil, 예를 들어, guard strongSelf = self else { return }.
Scott Gardner

@ t1 Swift 3에서 코드로 작성된 GCD 문서를 어디서 찾을 수 있습니까? Objective C로 작성된 것을 찾았습니다 . 여기 누군가 WWDC의 비디오를 가리키고 있었지만 Swift 3의 예제와 함께 공식 문서를 읽고 싶을 방법이 없습니다.
bibscy

1
.global(qos: .background)IO (네트워크 요청) 에는 사용하지 마십시오 . .global(qos: .default)또는 .global(qos: .utility)대신 사용하십시오 .
페드로 파울로 아모 림

28

XCode 8, Swift 3에서 컴파일 https://github.com/rpthomas/Jedisware

 @IBAction func tap(_ sender: AnyObject) {

    let thisEmail = "emailaddress.com"
    let thisPassword = "myPassword" 

    DispatchQueue.global(qos: .background).async {

        // Validate user input

        let result = self.validate(thisEmail, password: thisPassword)

        // Go back to the main thread to update the UI
        DispatchQueue.main.async {
            if !result
            {
                self.displayFailureAlert()
            }

        }
    }

}

12

OP 질문에 이미 답변되었으므로 속도 고려 사항을 추가하고 싶습니다.

DispatchQueue.global 에서 비동기 함수에 할당하는 우선 순위 클래스에 많은 차이가 있습니다 .

저전력 코어에 작업이 할당 된 것처럼 보이는 iPhone X에서 .background thread 우선 순위로 작업을 실행하지 않는 것이 좋습니다 .

다음은 XML 파일에서 버퍼링을 읽고 데이터 보간을 수행하는 계산 집약적 인 함수의 실제 데이터입니다.

장치 이름 / .background / .utility / .default / .userInitiated / .userInteractive

  1. 아이폰 X : 18.7 초 / 6.3 초 / 1.8 초 / 1.8 초 / 1.8 초
  2. 아이폰 7 : 4.6s / 3.1s / 3.0s / 2.8s / 2.6s
  3. 아이폰 5s : 7.3s / 6.1s / 4.0s / 4.0s / 3.8s

데이터 세트가 모든 장치에 대해 동일하지는 않습니다. iPhone X에서 가장 크고 iPhone 5에서 가장 작습니다.


1
훌륭한 정보. 나를 도와주었습니다
Morgz

1
@Myk 사용자가 시작했거나 결과를 기다리는 경우 .userInitiated 또는 .userInteractive 를 사용해야 다른 작업이 역 추적됩니다. 다른 대부분의 경우 .default 가 좋은 선택입니다.
Cosmin

6

나는 이것을했고 UITableView 또는 UIPickerView와 같이 사용자에게 알리지 않고 새 데이터를 표시하기 위해 UI를 새로 고치려는 경우 특히 중요합니다.

    DispatchQueue.main.async
 {
   /*Write your thread code here*/
 }

3
 DispatchQueue.main.async {
          self.collectionView?.reloadData() // Depends if you were populating a collection view or table view
    }


OperationQueue.main.addOperation {
    self.lblGenre.text = self.movGenre
}

// 뷰 컨트롤러에서 객체 (라벨, 이미지 뷰, 텍스트 뷰)를 채워야하는 경우 작업 대기열을 사용합니다.


2
   let concurrentQueue = dispatch_queue_create("com.swift3.imageQueue", DISPATCH_QUEUE_CONCURRENT) //Swift 2 version

   let concurrentQueue = DispatchQueue(label:"com.swift3.imageQueue", attributes: .concurrent) //Swift 3 version

Xcode 8, Swift 3에서 코드를 다시 작성했으며 Swift 2 버전과 달리 변경 사항이 표시되어 있습니다.


이것은 내가 쓴 것보다 깨끗해 보입니다. 감사.
gosborne3

2

스위프트 3

신속한 코드로 클로저를 호출하고 스토리 보드에서 변경하고 싶을 때 변경 유형이 변경되면 응용 프로그램이 중단됩니다.

하지만 응용 프로그램이 중단되지 않는 디스패치 방법을 사용하려고합니다.

비동기 방법

DispatchQueue.main.async 
{
 //Write code here                                   

}

동기화 방법

DispatchQueue.main.sync 
{
     //Write code here                                  

}

서비스 호출 시간에 비동기 메소드를 사용하고 싶습니다. 코드는 DispatchQueue.main.async {let objstory1 = self.storyboard? .instantiateViewController (withIdentifier : "HomeViewController") as! HomeViewController _ = self.navigationController? .pushViewController (objstory1, animated : false)}
Amul4608

1
사용하지 마십시오DispatchQueue.main.sync
trickster77777

메인 대기열의 동기화 호출은 확실히 문제를 일으킬 것입니다.
두부 전사

2
DispatchQueue.main.async(execute: {

// write code

})

시리얼 큐 :

let serial = DispatchQueue(label: "Queuename")

serial.sync { 

 //Code Here

}

동시 대기열 :

 let concurrent = DispatchQueue(label: "Queuename", attributes: .concurrent)

concurrent.sync {

 //Code Here
}

이것은 디스패치 큐를 생성하지 않으며 실행 루프를 통해 한 번의 틱 후 메인 큐에 배치합니다.
buildsucceeded


1
 let newQueue = DispatchQueue(label: "newname")
 newQueue.sync { 

 // your code

 }

1

신속한 5 업데이트

시리얼 큐

let serialQueue = DispatchQueue.init(label: "serialQueue")
serialQueue.async {
    // code to execute
}

동시 대기열

let concurrentQueue = DispatchQueue.init(label: "concurrentQueue", qos: .background, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil)

concurrentQueue.async {
// code to execute
}

에서 애플 문서 :

매개 변수

상표

계측기, 샘플, 스택 샷 및 충돌 보고서와 같은 디버깅 도구에서 고유하게 식별하기 위해 대기열에 첨부 할 문자열 레이블입니다. 응용 프로그램, 라이브러리 및 프레임 워크는 모두 고유 한 디스패치 큐를 만들 수 있으므로 역방향 DNS 명명 스타일 (com.example.myqueue)이 권장됩니다. 이 매개 변수는 선택 사항이며 NULL 일 수 있습니다.

qos

큐와 연관시킬 서비스 품질 레벨. 이 값은 시스템이 작업 실행을 예약하는 우선 순위를 결정합니다. 가능한 값 목록은 DispatchQoS.QoSClass를 참조하십시오.

속성

큐와 연관시킬 속성입니다. 태스크를 동시에 실행하는 디스패치 큐를 작성하려면 동시 속성을 포함하십시오. 해당 속성을 생략하면 디스패치 큐가 작업을 순차적으로 실행합니다.

자동 릴리스

대기열이 예약 한 블록에 의해 생성 된 객체를 자동 해제하는 빈도입니다. 가능한 값 목록은 DispatchQueue.AutoreleaseFrequency를 참조하십시오 .

표적

블록을 실행할 대상 큐입니다. 시스템이 현재 오브젝트에 적합한 큐를 제공하도록하려면 DISPATCH_TARGET_QUEUE_DEFAULT를 지정하십시오.


-3

이제는 간단합니다 :

let serialQueue = DispatchQueue(label: "my serial queue")

기본값은 직렬이며, 동시에 얻으려면 선택적 속성 인수 .concurrent를 사용하십시오.


을 추가하여 답변을 업데이트하는 것이 좋습니다 seiralQueue.async {}. @tylemol
DawnSong

-3
DispatchQueue.main.async(execute: {
   // code
})

이 코드 스 니펫에 감사드립니다. 즉각적인 도움이 될 수 있습니다. 적절한 설명 이것이 문제에 대한 좋은 해결책 인지 보여줌으로써 교육적 가치를 크게 향상시킬 것이며 , 유사하지만 동일하지 않은 질문을 가진 미래 독자들에게 더 유용 할 것입니다. 제발 편집 설명을 추가하고, 제한 및 가정이 적용 무엇의 표시를 제공하는 답변을.
Toby Speight

-4

swift 3.0에서이 코드를 사용하여 디스패치 큐를 생성 할 수 있습니다

DispatchQueue.main.async
 {
   /*Write your code here*/
 }

   /* or */

let delayTime = DispatchTime.now() + Double(Int64(0.5 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)                   
DispatchQueue.main.asyncAfter(deadline: delayTime)
{
  /*Write your code here*/
}

1
죄송합니다 . 디스패치 큐를 생성 하지 않고 실행 루프를 통해 한 번의 틱 후 기본 큐에 액세스하고 있습니다.
buildsucceeded
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.