Programlama

Swift’te Global Actor Nedir? Uygulamada Ne İşe Yarıyor?

Swift Concurrency tarafında kafayı en çok yakan sorulardan biri şu: “Actor tamam da, global actor tam olarak ne iş yapıyor?” Açık konuşayım — ilk bakışta bu konu baya soyut geliyor. Ben de 2023 yazında İstanbul’da bir iOS projesinde bunu ilk kez derinlemesine kurcaladığımda, önce “bu da başka bir süslü etiket herhalde” diye düşünmüştüm. Yanılmışım. Sonra iş büyüdü; ekran geçişleri, image processing ve ana thread hassasiyeti aynı anda aynı yerde toplanınca mevzu kendiliğinden netleşti.

İşin aslı şu ki global actor, normal actor gibi kendi içinde veri saklayan bir yapıdan çok, kodun belli parçalarını belirli bir executor’a bağlamak için var (yanlış duymadınız). Yani ortada bir “odacık” var ve sen bazı fonksiyonları, tipleri ya da değişkenleri o odacığa yolluyorsun. Tek tek kapı çalıyorsun resmen. Kulağa teorik geliyor, biliyorum — ama pratikte baya iş görüyor (bizzat test ettim)

Durun, bir saniye.

Normal Actor ile Global Actor Arasındaki İnce Çizgi

Önce temel farkı netleştirelim. Normal actor, içine koyduğun state’i seri şekilde korur —. Aynı anda iki iş gelip veriyi birbirine karıştırmasın diye kapıyı sıraya sokar. Global actor ise biraz daha dışarıdan çalışır; kendisini kullanmak yerine onunla işaretlenmiş kodu ilgili executor üzerinde koşturur.

Ben bunu ekip içinde anlatırken hep şöyle bir benzetme kullanıyorum: normal actor bir kasa gibi davranıyor, içindeki para ondan çıkmıyor ve kimse de aynı anda elini uzatamıyor. Neyse, global actor ise kasa değil… daha çok “bu masadaki işler yalnızca burada yapılır” tabelası gibi bir şey. Tabelayı asıyorsun, Swift geri kalanını hallediyor. Basit ama etkili.

Evet, doğru duydunuz.

Bir şey dikkatimi çekti: Mesela küçük bir startup ortamında tek kişi çalışıyorsanız bu fark başta önemsiz görünebilir. Ama ürün büyüyüp aynı anda görüntü işleme, ağ isteği ve UI güncellemesi aynı uygulamada dönmeye başlayınca tablo tamamen değişiyor; bir noktada “neden bazen garip race condition görüyorum?” sorusu çıkıyor ortaya ve işte tam o noktada global actor temiz bir sınır çiziyor.

Kavram Ne yapar? Nerede iyi çalışır?
Normal Actor Kendi kapsadığı state’i seri erişime açar Paylaşılan veri koruma
Global Actor Belirli kodu ortak bir executor’a bağlar UI, image processing, merkezi iş akışları

Neden Global State Korkutuyor?

Global state denince benim aklıma hep eski projeler geliyor. En çok da de 2022’de Ankara’da bir müşteri uygulamasında yaşadığımız olay hâlâ zihnimin bir köşesinde duruyor: tek bir cache nesnesi vardı ve farklı task’ler ona eşzamanlı dokunuyordu. Sonuç? Bir kullanıcıya ait veri neredeyse ötekine sızacaktı. Neyse ki erken yakaladık ama mesele ciddiymiş, valla ciddi.

Concurrent programlarda tehlike tam da burada başlıyor (ciddiyim). Biri yazarken diğeri okuyor, üçüncü biri de silmeye kalkıyor… Ortalık hafif karışıyor yani. Global actor bu karmaşayı azaltmak için devreye giriyor; o değerleri veya fonksiyonları seri erişime zorluyor. Sihir değil — sadece düzen.

Global actor’ın en büyük olayı “veriyi sihirli biçimde güvenli yapmak” değil; erişimi düzenlemek. Bu ayrım önemli çünkü bazen ekipler onu yanlış anlayıp her şeyi çözecek mucize gibi görüyor.

💡 Bilgi: @MainActor da aslında bir global actor’dür. Yani arayüz tarafındaki işleri ana thread/executor üzerinden sıralamak için kullanılan özel bir örnek gibi düşünebilirsin.

@globalActor Nasıl Tanımlanıyor?

Tuhaf ama, Kendi global actor’ını tanımlamak için Swift sana gayet net bir yol veriyor: @globalActor. Bu etiketle birlikte türün GlobalActor protokolüne uyması gerekiyor ve içeride zorunlu olarak shared adında tekil örnek sağlamalısın.

Şimdi gelelim işin can alıcı noktasına.

Ama şunu da söyleyeyim — buradaki kritik detay sadece söz dizimi değil, tasarım niyeti de önemli. Eğer private init kullanmazsan başka bir instance yaratılabilir ve bütün fikir bozulur. Geçen ay İzmir’deki bir freelance projede bunu test ederken bilerek init’i açık bıraktım; evet, ikinci örnek oluşturulabiliyor ve beklediğin izolasyon hissi anında dağılıyor. Pek hoş değil, inanın. Pixel Referral Program Geri Döndü: 10% İndirim, 50$ Kredi yazımızda bu konuya da değinmiştik.

@globalActor
actor ImageProcessing {
static let shared = ImageProcessing()
private init() {}
}

Neyi anotlayabilirsin?

Garip gelecek ama, Burası güzel kısım. Global actor yalnızca sınıflara yapışıp kalmıyor — değişkenleri de işaretleyebiliyorsun, fonksiyonları da, tipleri de. Yani kapsam fena değil, hatta beklediğimden geniş çıktı açıkçası.

  • Değerler: global değişkenler ya da statik alanlar
  • Tipler: class, struct veya benzeri yapılar
  • Fonksiyonlar: belirli işi o executor altında koşturmak için (bence en önemlisi)

Bunu günlük hayattan düşünürsen şöyle oluyor: mutfağa sadece yemek yapanların girmesi lazım diyorsun, tabağı taşıyan oraya girmezse daha rahat edersin (ben de ilk duyduğumda şaşırmıştım). Her şey tek elde sıralanıyor ve kimse birbirinin ayağına basmıyor.

@MainActor Neden Özel Duruyor?

Bilmem anlatabiliyor muyum, @MainActor konusu ayrı bir başlık gibi görünse de mantık aynı aileden geliyor (kendi tecrübem). Hani. UI güncellemeleri iOS dünyasında hassas işlerden biridir; düzensiz thread kullanımı ekranda saçma davranışlara yol açabiliyor. Ben bunu ilk kez eski bir tablo görünümünde yaşadım — hücreler bazen geç çiziliyor, bazen hiç görünmüyordu. Mantıklı değil mi? Çıldırıyordum. Daha fazla bilgi için Veri Etiketleme Altın Madeni: Handshake ve Mercor Patlaması yazımıza bakabilirsiniz.

@MainActor ile Swift şunu söylüyor: bu kod parçası ana executor üzerinde çalışsın. Yani arayüzü güvende tutmaya çalışan resmi trafik polisi gibi düşünebilirsin. Her şey hızla gitmek zorunda değil; bazen sıraya girmek daha akıllıca olur.

Küçük proje ile kurumsal proje arasında fark ne?

Küçük projede belki birkaç ekran olduğu için @MainActor kullanımını az görürsün. Ama enterprise seviyeye çıktığında durum değişir; onlarca ekran, yoğun network trafiği. Background işlem derken UI tarafını disipline etmek şart oluyor, başka çaren kalmıyor.

E tabi burada şunu da söylemek lazım: her şeyi @MainActor’a yüklemek çözüm değil. Bazen geliştiriciler güvenlik hissine kapılıp gereksiz yere tüm sistemi ana aktöre bağlar; sonra performans düşer, akıcılık gider. Beklediğin kadar iyi olmaz yani. Dengeyi bulmak lazım. Bu konuyla ilgili Ola Web’in Sıkışık Haritası: Küçük UX Açıkları yazımıza da göz atmanızı tavsiye ederim.

Peki Pratikte Nasıl Kullanılır?

Diyelim ki görüntü işlemesi yapan ayrı bir akışın var. Bunun seri olmasını istiyorsun — yani aynı anda iki fotoğrafı boyamaya kalkmasın istiyorsun mesela. O zaman kendi global actor’ını tanımlayıp bu işi onun üstüne yüklersin. Gayet temiz.

@ImageProcessing
func resizeAndFilter(_ image: UIImage) async -> UIImage {
// işlem burada serial yürür
return image
}
@ImageProcessing
var lastProcessedImageID: String = ""

Bence güzel tarafı şu: kod okunurken niyet hemen anlaşılıyor. “Bu iş image pipeline’a ait” diyorsun ve nokta koyuyorsun. Ancak ufak bir hayal kırıklığı kısmı da var — her problemde sihirli çözüm değil bu yapı. Yanlış mimariyi cilalamaktan öteye gitmeyebilir, bunu da söylemek istedim.

Neden singleton’a benziyor ama tam aynı şey değil?“text
Singleton -> “Bana ulaşın”
Global Actor -> “Bu etiketi taşıyan kodu buradan geçir”
“`

Bazen insanlar ikisini karıştırıyor çünkü ikisinde de tekil merkez fikri var gibi duruyor. Fakat singleton’da genelde nesnenin kendisini kullanırsın; global actor’da ise nesnenin çevresinde dolaşırsın ve sadece onunla işaretlenmiş kodu uygun executor’a yönlendirirsin. İnce ama önemli bir fark bu.

Sorulara Kısa Kısa Cevap Verelim mi?

| Soru | Kısa cevap |
|—|—|
| Actor regular ile global arasındaki fark ne? | Regular actor kendi state’ini korur; global actor dışarıdaki kodu belirli executor’a bağlar |
| Neyi anotlayabilirim? | Değerler, tipler ve fonksiyonlar |
| Private init neden gerekli? | Başka instance oluşup tasarımı bozmasın diye |
| @MainActor neden global actor sayılıyor? | Ana executor üzerinde seri erişim sağladığı için |

Lafı gevelemeden söyleyeyim: bu tabloyu kafada tutarsan konunun yüzde sekseni oturuyor zaten. Gerisi deneyimle geliyor.

Tasarım Tarafında Nerede Parlıyor?

Bence, Bana göre global actor’ların en güçlü olduğu yer medya işleme senaryoları. Mesela filtre uygulama motoru düşünelim — kullanıcı art arda on fotoğraf seçtiğinde hepsini paralel ezmek yerine sıraya almak daha mantıklı olabiliyor, özellikle cihaz kaynakları zayıfsa. Böyle durumlarda seri yürütme hem tahmin edilebilirlik hem hata ayıklama açısından gerçekten rahatlatıyor. Bunu bizzat test etmişliğim var, idare eder demeyeyim, şaşırdım açıkçası.

Buna karşılık her şeyi serial yapmak da tuzak olabilir. Performans ihtiyacı yüksek olan sistemlerde aşırı kısıtlama yeni darboğaz yaratır (ciddiyim). Yani araç doğru ama el frenini sürekli çekili tutarsan araba yine gitmez. Siz ne dersiniz? Bu kadar.

Ekip içinde nasıl anlatırım?

Editör masasındaki notum şu olmuştu: “Global actor = güvenlik kilidi değil, sıra memuru.” Bunu ekip arkadaşlarıma söylediğimde konu anlaşıldı desem yeridir. Çünkü herkes doğrudan data safety sanıyordu; halbuki mesele çoğu zaman access coordination’dı. Hmm, basit ama akılda kalıcı bir ayrım.

Kısacası küçük takımlar için basitlik getiriyor, büyük takımlar içinse kaos azalıyor. Ama yanlış yerde kullanırsan fazladan soyutlama katmanı olur — hani gereksiz bürokrasi gibi. O kadar kötü olmasa da yakın.

Sıkça Sorulan Sorular

Swift’te global actor nedir?

Global actor, bazı değişkenleri, tipleri veya fonksiyonları belirli bir executor altında çalıştırmak için kullanılan özel bir concurrency aracıdır. Normal actor’dan farkı, kapsadığı state yerine dışarıdaki kodu yönlendirmesidir.

@globalActor ile custom actor nasıl tanımlanır?

@globalActor etiketiyle birlikte türün GlobalActor protokolünü karşılaması gerekir. Statik shared örneği tanımlanmalıdır. Genelde ayrıca private init kullanılır ki ikinci örnek oluşmasın.

Neden private init() öneriliyor?

Kendi deneyimimden konuşuyorum, Aynı type’tan ikinci instance oluşturulmasını engellemek için öneriliyor.Çünkü amaç tekil executor mantığını korumak.Birden fazla instance olursa modelin sade yapısı bozulur.

@MainActor neden önemli?

@MainActor UI ile ilgili işleri ana thread/executor üzerinde sıraladığı için önemlidir.Arayüz güncellemelerinde race condition riskini azaltır ve davranışı daha öngörülebilir hale getirir.

Dış Kaynaklar Düşünülmeden Olmazdı!

      1. Sıkça Sorulan Sorular cevaplandı mı?

        Hmm… neredeyse bitirdik.

        Neyse uzatmayalım.

        Kaynaklar İleri Okuma

        Swift Book — Concurrency Bölümü

        Apple Developer Documentation — GlobalActor

        Swift Concurrency Course / Global Actors Yazısı

        Agentic AI üzerine yazımızda bahsettiğimiz otonomi fikri burada farklı biçimde karşımıza çıkıyor; sistem davranışı merkezileşince kontrol kolaylaşıyor.

        Hızlı teslim süreçlerinde gördüğümüz koordinasyon ihtiyacı, concurrency tarafında benzer şekilde düzen istiyor.

        Aşkın KILIÇ

        20+ yıl deneyimli Azure Solutions Architect. Microsoft sertifikalı bulut mimari ve DevOps danışmanı. Azure, yapay zekâ ve bulut teknolojileri üzerine Türkçe teknik içerikler üretiyor.

        AZ-305AZ-104AZ-500AZ-400DP-203AI-102

        Bu içerik işinize yaradı mı?

        Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.

        Haftalık Bülten

        Her pazar özenle seçilmiş teknoloji yazıları doğrudan e-postanıza gelsin.

        ← Onceki Yazi
        Pixel Referral Program Geri Döndü: 10% İndirim, 50$ Kredi
        Sonraki Yazi →
        İlk Erken Erişim Darbesi: Nels Anderson Pes Etmedi

        Yorum Yaz

        E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

        Haftalık Bülten

        Azure, DevOps ve Yapay Zeka dünyasındaki en güncel içerikleri her hafta doğrudan e-postanıza alın.

        Spam yok. İstediğiniz zaman iptal edebilirsiniz.
        📱
        Uygulamayı Yükle Ana ekrana ekle, çevrimdışı oku
        Kategoriler
        Ara
        Paylaş
        İçindekiler
        ← Pixel Referral Program Geri Dö...
        İlk Erken Erişim Darbesi: Nels... →
        📩

        Gitmeden önce!

        Her pazar özenle seçilmiş teknoloji yazıları ve AI haberleri doğrudan e-postanıza gelsin. Ücretsiz, spam yok.

        🔒 Bilgileriniz güvende. İstediğiniz zaman ayrılabilirsiniz.

        📬 Haftalık bülten: Teknoloji + AI haberleri