Swift 3'te dağıtım kuyruğu nasıl oluşturulur


403

Swift 2'de, aşağıdaki kodla kuyruk oluşturabildim:

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

Ama bu Swift 3'te derlenmiyor.

Swift 3'te bunu yazmanın tercih edilen yolu nedir?



Swift 4'te seri kuyruk oluşturmak için 3 ekstra parametre vardır. Bir seri kuyruk oluşturmak için nasıl kullanılır? DispatchQueue.init (label:, qos:, öznitelikler:, autoreleaseFrequency:, target
:)

@ nr5 Kuyruklar varsayılan olarak seridir, bu nedenle yalnızca DispatchQueue(label: "your-label")bir seri kuyruk için kullanmak yeterlidir . Ek parametrelerin tümü varsayılan değerlere sahiptir.
jbg

Yanıtlar:


1131

Eşzamanlı bir kuyruk oluşturma

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

}  

Seri kuyruk oluşturma

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

}

Ana kuyruğu eşzamansız olarak alın

DispatchQueue.main.async {

}

Ana kuyruğu senkronize edin

DispatchQueue.main.sync {

}

Arka plan iş parçacığından birini almak için

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

}

Xcode 8.2 beta 2:

Arka plan iş parçacığından birini almak için

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

}

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

Eğer kullanma hakkında bilgi edinmek istiyorsanız bu sıralar bu .Sağlıklı cevabı


3
Aslında atlayabilirsiniz attributes: .serialbir seri kuyruğu oluştururken: let serialQueue = DispatchQueue(label: "queuename").
kean

15
Xcode 8 beta 4'te .serial seçeneği yoktur, bu nedenle özniteliklerde .concurrent öğesini atlayarak seri kuyruk oluşturmanız gerekir.
Oleg Sherman

Swiftc DispatchQueue erişmek gerekir ama aşağıdaki hatayı aldım '__strong dispatch_queue_t' (aka 'NSObject <OS_dispatch_queue> * __ strong') bir değişken 'dispatch_queueue yaparken bir tür değer ile başlatılamıyor = [SwiftClass Sırası]; Bu hızlı bir DispatchQueue değişkeni
ideerge 29:16

Swift 3.0'da DispatchQueue.main.asynchronously (DispatchQueue.main) {self.mapView.add (self.mapPolyline)}, DispatchQueue.global (). İle eşzamansız olarak (DispatchQueue.main) {self.mapView.add (self .mapPolyline)}, ancak her ikisi de "dispathQuoue türünün değeri eşzamansız olarak üye yok" ile aynı hatayı gösteriyor
Abirami Bala

1
OP kodundan elma neden "com.swift3.imageQueue" kullanmaya odaklanıyor ? Etiketin 3 parça olduğunu görüyorum. Neden? her parça ne anlama geliyor? Biçimlendirmeyi alamıyorum
Honey

55

> = Swift 3 altında derler . Bu örnek, ihtiyacımız olan sözdiziminin çoğunu içerir.

QoS - yeni hizmet kalitesi sözdizimi

weak self - tutma döngülerini bozmak

eğer benlik yoksa hiçbir şey yapma

async global utility queue- ağ sorgusu için, sonucu beklemez, eşzamanlı bir kuyruktur, blok (genellikle) başlatıldığında beklemez. Eşzamanlı bir sıra için istisna, daha önce görev sınırına ulaşıldığında, sıra geçici olarak bir seri kuyruğa dönüşür ve bu sıradaki önceki bir görevin tamamlanmasını bekler.

async main queue- Kullanıcı arayüzüne dokunmak için blok sonucu beklemez, ancak başlangıçta yuvasını bekler. Ana kuyruk bir seri kuyruktur.

Tabii ki, buna bir miktar kontrol eklemeniz gerekiyor ...

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
Swift 3'te kodlama yaparken, önceki kodunuzun% 30'unu yoğunlaştırmaya ve silmeye
alışın

[Zayıf benlik] örneği için teşekkürler!
imike

1
Daha iyi içelim guardo selfdeğil nilo eğer kod hiçbiri yürütülür böylece, üst kısmında nil, örneğin guard strongSelf = self else { return }.
Scott Gardner

@ t1 Swift 3'te kodla yazılmış GCD belgelerini nerede bulabileceğimi söyleyebilir misiniz? Sadece Amaç C'de yazılmış olanı buldum . Buradaki biri beni WWDC'den bir videoya yönlendiriyordu, ancak Swift 3'teki örneklerle resmi belgeleri okumak istiyorum ve bunu bulmanın bir yolu yok.
bibscy

1
.global(qos: .background)ES için kullanmayın (ağ isteği). Kullanın .global(qos: .default)veya .global(qos: .utility)bunun yerine.
Pedro Paulo Amorim

28

XCode 8, Swift 3'te derlendi 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 sorusu yukarıda yanıtlandığı için sadece bazı hız değerlendirmeleri eklemek istiyorum:

DispatchQueue.global'daki zaman uyumsuzluk işlevinize atadığınız öncelik sınıfını büyük ölçüde fark eder .

.Background ile görevleri çalıştırmanızı önermiyorum özellikle düşük güç çekirdeği üzerinde görev tahsis gibi görünüyor iPhone X iş parçacığı önceliği .

Bir XML dosyasından (arabelleğe alma ile) okuyan ve veri enterpolasyonu yapan hesaplama açısından yoğun bir fonksiyondan bazı gerçek veriler:

Aygıt adı / .background / .utility / .default / .userInitiated / .userInteractive

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

Veri kümesinin tüm cihazlar için aynı olmadığını unutmayın. İPhone X'in en büyüğü ve iPhone 5'lerin en küçüğü.


1
Harika bilgi. Bana yardım etti
Morgz

1
@Myk Kullanıcı başlattıysa ve / veya sonuçları bekliyorsa .userInitiated veya .userInteractive kullanmanız gerekir, böylece diğer işlemler geri izlenir . Diğer çoğu durumda .default iyi bir seçim olacaktır.
Cosmin

6

Bunu yaptım ve kullanıcı UITableView veya UIPickerView gibi fark etmeden yeni verileri göstermek için UI yenilemek istiyorsanız bu özellikle önemlidir.

    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
}

// görünüm denetleyicinizdeki nesneleri (etiketler, görüntü görüntüleme, metin görünümü) doldurmanız gerekiyorsa İşlem Sırasını kullanın


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

Kodunuzu Xcode 8, Swift 3'te yeniden çalıştım ve değişiklikler Swift 2 sürümünüzün aksine işaretlendi.


Yazdığımdan daha temiz görünüyor. Teşekkürler.
gosborne3

2

Hızlı 3

hızlı kod bazı kapatma çağırmak istiyorsanız sonra storyboard değiştirmek istiyorum ya herhangi bir tür kapalı değişiklik uygulamanızın görüntülemek için aittir

ancak gönderim yöntemini kullanmak istediğinizde uygulamanız çökmeyecek

zaman uyumsuz yöntem

DispatchQueue.main.async 
{
 //Write code here                                   

}

senkronizasyon yöntemi

DispatchQueue.main.sync 
{
     //Write code here                                  

}

Servis çağırma zaman kodum DispatchQueue.main.async {let objstory1 = self.storyboard? .İnstantiateViewController (withIdentifier: "HomeViewController") olarak kullanmak istiyorum! HomeViewController _ = self.navigationController? .PushViewController (objstory1, canlandırılmış: false)}
Amul4608 18:17 '

1
Asla kullanmayınDispatchQueue.main.sync
trickster77777

Ana kuyruktaki senkronizasyon çağrıları kesinlikle sorunlara neden olacaktır.
Tofu Warrior

2
DispatchQueue.main.async(execute: {

// write code

})

Seri Sıra:

let serial = DispatchQueue(label: "Queuename")

serial.sync { 

 //Code Here

}

Eşzamanlı kuyruk:

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

concurrent.sync {

 //Code Here
}

Bu bir gönderme kuyruğu oluşturmaz, sadece çalıştırma döngüsü boyunca bir onay işaretinden sonra sizi ana kuyruğa koyar.
17'de


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

 // your code

 }

1

Swift 5 için güncelleme

Seri Sıra

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

Eşzamanlı Sıra

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

concurrentQueue.async {
// code to execute
}

Gönderen Elma belgelerinde :

Parametreler

etiket

Kuyruğa Aletler, örnek, yığın görüntüleri ve kilitlenme raporları gibi hata ayıklama araçlarında benzersiz olarak tanımlamak için kuyruğa eklenecek dize etiketi. Uygulamalar, kütüphaneler ve çerçevelerin tümü kendi dağıtım kuyruklarını oluşturabildiğinden, ters DNS adlandırma stili (com.example.myqueue) önerilir. Bu parametre isteğe bağlıdır ve NULL olabilir.

qos

Kuyrukla ilişkilendirilecek hizmet kalitesi düzeyi. Bu değer, sistemin görevleri yürütme için zamanlama önceliğini belirler. Olası değerlerin listesi için bkz. DispatchQoS.QoSClass.

Öznitellikler

Kuyrukla ilişkilendirilecek öznitelikler. Görevleri aynı anda yürüten bir gönderme kuyruğu oluşturmak için eşzamanlı özniteliği ekleyin. Bu özniteliği atlarsanız, gönderme kuyruğu görevleri seri olarak yürütür.

autoreleaseFrequency

Sıranın zamanladığı bloklar tarafından oluşturulan nesnelerin otomatik olarak serbest bırakılma sıklığı. Olası değerlerin listesi için, bkz. DispatchQueue.AutoreleaseFrequency .

hedef

Blokların çalıştırılacağı hedef kuyruk. Sistemin geçerli nesne için uygun bir kuyruk sağlamasını istiyorsanız DISPATCH_TARGET_QUEUE_DEFAULT belirtin.


-3

şimdi basitçe:

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

varsayılan seri, eşzamanlı almak için isteğe bağlı özellikler bağımsız değişkenini kullanırsınız. concurrent


Cevabınızı ekleyerek güncellemeniz daha iyi olur seiralQueue.async {}. @tylemol
DawnSong

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

Anında yardım sağlayabilecek bu kod snippet'i için teşekkür ederiz. Düzgün bir açıklama , bunun neden problem için iyi bir çözüm olduğunu göstererek eğitim değerini büyük ölçüde artıracak ve benzer, ancak aynı olmayan soruları olan gelecekteki okuyucular için daha yararlı hale getirecektir. Lütfen açıklama eklemek için cevabınızı düzenleyin ve hangi sınırlamaların ve varsayımların geçerli olduğunu belirtin.
Toby Speight

-4

Swift 3.0'da bu kodu kullanarak gönderme kuyruğu oluşturabilirsiniz

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
Üzgünüz, bu bir gönderme kuyruğu oluşturmuyor , çalıştırma döngüsünde bir onay işaretinden sonra ana kuyruğa erişiyor.
17'de
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.