Merhaba bu yazımızın konusu ‘DispatchWorkItem‘.
DispatchWorkItem kuyrukların Thread’ler aracılığıyla execute edebileceği öğelerdir. Mesela yaygın olarak kullanılan asyncAfter methodu bizden bir WorkItem öğesi bekler.

Initialize
DispatchWorkItem oluşturursak bizden başlatma değerleri olarak ;
DispatchQos, DispatchWorkItemFlags, ve bir completionBlock ister

Biz şu an için qos ve flags’ı default kullanalım ve completionBlock ile birlikte başlatım.
Create
Başlatmanın ardından Completion Block içerisinde DispatchWorkItem’ın işini belirtiyoruz. Aşağıdaki örnekte workItem execute edildiğinde print fonksiyonumuz çalışıcak. Şu an workItem başarıyla oluşturuldu fakat çağırılmadı, tetiklenmeyi bekliyor.

Execute
Oluşturuduğumuz DispatchWorkItem‘ı execute etmenin farklı yolları var. Mesela aşağıdaki şekilde perform() ile şimdiki Thread üzerinden senkron bir şekilde execute edebiliriz.

Ve ya herhangi bir kuyruk aracılığıyla asenkron bir şekilde execute edebiliriz.

Notify
Execute işlemininin bittiğini notify() ile haber alabiliriz.

Cancel
Oluşturduğumuz DispatchWorkItem öğelerini henüz execute edilmediyse iptal edebiliriz. Mesela şöyle bir örnek olsun. Kullanıcı bir butona basıyor bastıktan 1 saniye sonra ekrana bir animasyon çıkıyor çıkan animasyon 2 saniye sonra kayboluyor. Kullanıcının butonu spamleyip sürekli tıkladığını düşünelim ve buna karşı önlem alalım.
Code
Önce optional bir DispatchWorkItem oluşturuyorum.

Ardından kullanıcı butona bastığında animasyonu oluşturucak taslak bir fonksiyon yazıyorum. Yazdığım fonksiyonu inceleyecek olursak ;

Sonucu görmek adına fonksiyon her çalıştığında ilk satırda bir print alıyorum. İkinci satırı şu an için geçiyorum. Üçüncü satırda bir DispatchWorkItem oluşturuyorum ardından yapacağı işi belirtiyorum ardından bunu dışarıda oluşturduğum DispatchWorkItem‘a eşitliyorum ve bu DispatchWorkItem‘ı Main Thread üzerinde çalıştırıyorum.
Kullanıcının butonu spamlediğini düşünüyorduk diyelim ki kullanıcı butona art arda 9 defa tıkladı alacağımız çıktı şu şekilde ;

Fonksiyon 9 defa çağırıldı fakat DispatchWorkItem sadece 1 defa çalıştı. Çünkü her çağrıldığında, kuyrukta olan ve çağrıldığı andan 1 saniye sonra koşulacak olan bir önceki DispatchWorkItem öğesi iptal ediliyor ve kuyruktan çıkarılıyor.
Yani kullanıcı 1.tıklamayı yaptığında, kuyruğa 1 saniye sonra çalışacak bir işlem eklendi. Henüz 1 saniye geçmeden kullanıcı 2.tıklamayı yaptığında ise 1.tıklamada kuyruğa giren işlem iptal edildi ve 2.tıklamanın işlemi kuyruğa girdi. Yani her tıklama bir önceki işlemi iptal edip kuyruğa girdi. En son tıklamaya yani 9.tıklamaya gelirsek 8. tıklamanın yerine geçti ve kullanıcı 1 saniye boyunca işlem yapmadığı için DispatchWorkItem çalıştı.
Result
Yukarıda basit bir örnek oluşturduk. DispatchWorkItem perform(), notify(), cancel() methodlarını kullanarak gerekli işlemleri iptal edebilir, sonucunda haber alabilir farklı kuyruklarda çağırabiliriz.