Swift: Multithreading

Uygulamanızdaki kodları DispatchQueue API’ını kullanarak farklı thread’lerde çalıştırın!

Baran Önen
TurkishKit
4 min readApr 28, 2021

--

Merhaba sevgili TurkishKit okuyucuları.👋 Bu yazımızda uygulamanızda bitirilmesi uzun süren bir kod çalıştırdığınızda arayüzün donmamasını sağlarken kullanacağınız “multithreading” özelliklerinden bahsedeceğim.

Öncelikle yapacağımız şey hakkında biraz temel bilgi elde edelim.🧑‍💻

İşlemciler, aynı anda sadece bir işlemi gerçekleştirmek için tasarlanmıştır. Zamanla aynı anda çalışan işlemlerin sayısı arttıkça bu işlemlerin tümünü daha hızlı bir şekilde yapabilmek için çoklu çekirdekli işlemciler ortaya çıkmıştır.📈

Aslında şu an satılan bilgisayar işlemcilerindeki her bir çekirdek, ayrı bir işlemciyi temsil etmektedir.

Bilgisayardaki işlemlere ise thread adı verilmektedir. Bir uygulama birden fazla thread’e sahip olabilir. Böylece aynı anda birden fazla işlem yapabilir.

Ayrıca bir işlemci/çekirdek de aynı anda birden fazla thread çalıştırabilir. Bunu, çalışması gereken thread’leri sıraya koyarak yapar.

Normalde yazdığınız bir uygulamada kodlar, arayüz ile aynı thread’de çalışarak uzun bir işlem gerçekleştiğinde arayüzün donmasına sebep olabilir. ⚠️ Bu da kullanıcı deneyimi için tahmin edebileceğiniz gibi hiç güzel bir şey olmayacaktır. 😬

Swift’te birden fazla thread oluşturmak için Apple’ın sunduğu DispatchQueue API’ını kullanabiliriz.

DispatchQueue’nun nasıl kullanıldığını göstermek için sırayla Apple’dan bazı isimlere “Merhaba, isim” şeklinde cümleler yazan bir uygulama geliştireceğiz.

Öncelikle sadece bir isime hoşgeldin mesajı yazarak uygulamanın temelini atalım.

Uygulamamız sorunsuz bir şekilde çalışıyor. Şimdi isimlerin listesini tutması için bir dizi ve şu anki ismi tutması için bir değişken oluşturalım. Bu isimleri sırayla değiştirmesi için ise onAppear metodunu ve for döngüsünü kullanalım.

Uygulamamız şu an çalışıyor ancak ekranda hiç bir şey gözükmüyor. Bunun sebebi ise onAppear metodunun içine yazdığımız kod çalıştırılırken arayüzün güncellenememesi.

Başka bir deyişle isimleri sırayla değiştirdiğimiz kod çalışıyor ancak bir thread aynı anda sadece bir işlemi yapabildiği için arayüz yeni isimlerle güncellenemiyor.

Şimdi onAppear metodunun içindeki kodu aşağıdaki ile değiştirelim:

Uygulamamız tekrardan istediğimiz gibi çalışıyor. Verdiğimiz belirli bir süre aralığı ile “Merhaba, isim” cümlesinin isim kısmı değişiyor.

Peki bunu sağlayan ne?

DispatchQueue aracılığıyla oluşturduğumuz yeni thread, içindeki while döngüsünün asenkron olarak başka bir yerde çalışmasını sağlayarak arayüzün thread’ini durdurmuyor.

DispatchQueue.global() metodunu kullanırken verdiğimiz qos argümanı parametresi “quality of service”, yani servis kalitesi anlamına geliyor. Sistem, yeni thread’e bu argümanda belirttiğimiz şekilde öncelik tanıyor.

“qos” argümanının alabileceği değerler ise aşağıdaki gibidir:

  • userInteractive: Çalışan işlemin kullanıcı ile interaktif bir şekilde çalıştığını belirtir. Animasyonlar gibi kullanıcı arayüzünü güncelleyen işlemlerde kullanılabilir.
  • userInitiated: Kullanıcı arayüzüyle direkt olarak bağlantılı olmasa da çalıştığı süre boyunca kullanıcıların uygulamayı kullanmasını engelleyen işlemlerde kullanılabilir.
  • default: İşlemin önceliğine sistem tarafından karar verilecektir.
  • utility: Kullanıcının aktif olarak takip etmediği işlemlerde kullanılabilir.
  • background: Temizlik veya bakım için arkada çalışan, uzun sürebilecek işlemler için kullanılabilir.

Bu değerler, sistemin önemli thread’lere öncelik vermesi için kullanılsa da tek kullanım alanı bu değil. Bildiğiniz gibi Apple, bir süredir yongalarına farklı güçte işlemci çekirdekleri koyuyor.

Örneğin A14 çipinde 2 tane yüksek performans, 4 tane de yüksek verimlilik çekirdeği bulunuyor. İşlemler, ne kadar güç gerektirdiğine göre otomatik olarak gerekli çekirdeklerde çalıştırılıyor.

DispatchQueue kullanırken dikkat etmeniz gereken başka bir şey de yeni işlemin asenkron veya senkron olduğu.

onAppear metodundaki kodu aşağıdaki kod ile değiştirelim:

Uygulamamız tekrardan çalışmıyor. Bunun sebebi, yeni bir işlem oluşturmamıza rağmen bu işlemi senkron olarak oluşturmamız. Senkron olarak oluşturduğumuz işlem, bitmeden önce kendinden sonraki işlemin gelmesini engelliyor. Böylece ilk durumdaki gibi arayüz, yazdığımız kod çalışırken güncellenemiyor.

Başka bir deyişle, onAppear fonksiyonunun içindeki kod farklı bir işlemde çalışsa bile bitene kadar diğer kodların çalışmasını engelliyor. Diğer kodların içinde SwiftUI ile yazdığımız arayüz de bulunduğu için arayüzdeki güncellemeleri göremiyoruz.

Gördüğünüz gibi Apple, uygulamamızda birden fazla thread kullanabilmemiz için kullanımı oldukça kolay bir API sunuyor. 🎉 DispatchQueue adındaki bu API sayesinde thread’lerin önemleri ve senkron/asenkron oldukları belirtilebiliyor. Geriye kalan bütün işlemleri ise sistem gerçekleştiriyor.

Ben örnekleri SwiftUI ile yazılmış bir arayüz kullanarak göstersem de bu API’ı kullanabilmek için tabii ki SwiftUI kullanmamız gerekmiyor. DispatchQueue, Swift ile yazılan her türlü uygulamada kullanılabiliyor.

Umarım sorununuzu çözmenize yardımcı olabilmişimdir. Bir sonraki yazımızda görüşmek üzere.👋

Bizi daha yakından takip etmek istiyorsanız, sosyal medya hesaplarımıza aşağıdan ulaşabilirsiniz!

Twitter | Instagram | Facebook

--

--