Bu kılavuz, Objective-C programlama dilinde multithreading ve eşzamanlılık konularını inceleyerek uygulamalarımızın performansını artırma ve arayüzlerimizin daha akıcı hale gelmesini sağlama yöntemlerini açıklamaktadır Makale, Grand Central Dispatch GCD çerçevesi içindeki Dispatch Queues yapısı, serial ve concurrent queue yapıları, eşzamanlı programlama yöntemi, thread safety ve lock-unlock fonksiyonları, UI Thread ve Perform Selector On Main Thread yöntemleri gibi konuları ele almaktadır Ayrıca, multithreading işlemleri için kullanabileceğimiz yöntemler de tartışılmaktadır
Bu makale, Objective-C programlama dilinde multithreading ve eşzamanlılık konularını incelemek için bir kılavuz niteliğindedir. Multithreading, bir uygulamanın aynı anda birden fazla işlem yapabilmesini sağlayan bir programlama yöntemidir. Bu yöntemi kullanarak uygulamalarımızın performansını artırabilir ve arayüzümüzün daha akıcı olmasını sağlayabiliriz.
Makalede, Grand Central Dispatch (GCD) çerçevesi içinde yer alan Dispatch Queues başta olmak üzere serial queue, concurrent queue ve block yapısı hakkında bilgiler verilecektir. Ayrıca, birden fazla işlemin aynı anda yürütüldüğü eşzamanlı programlama yöntemi, thread safety konusu ve lock-unlock fonksiyonlarına da değinilecektir. Kullanıcının arayüzü ile etkileşim kurduğu iş parçacığı olan UI Thread ve Perform Selector On Main Thread yöntemi de ele alınacaktır. Son olarak, Dispatch Queues ve NSOperationQueue gibi multithreading işlemleri yapmak için kullanabileceğimiz yöntemler de tartışılacaktır.
Multithreading Nedir?
Multithreading, aynı anda birden fazla işlem yapabilen bir programlama yöntemidir. Uygulamalar, bir işlemi tamamlamadan diğer işlemlere geçebilir ve böylece işlemler arasındaki bekleme süresi azaltılabilir. Özellikle iOS uygulamalarında, kullanıcıların hızlı tepki veren ve akıcı bir arayüze sahip olması çok önemlidir. Bu nedenle multithreading kullanmak, uygulamaların performansını artırabilir ve arayüzlerinin daha akıcı hale gelmesini sağlayabilir.
Neden Multithreading Kullanmalıyız?
Multithreading, bir uygulamanın aynı anda birden fazla işlem yapabilmesini sağlar. Bu da uygulamaların performansını artırır ve arayüzlerinin daha akıcı olmasını sağlar. Özellikle büyük boyutlu dosyaları işlemek, veritabanı sorgularını yapmak, ağ iletişimi kurmak gibi işlemler için çoklu işlemci kullanmak önemlidir.
Birçok kullanıcının aynı anda uygulamayı kullanması veya aynı anda birçok işlem yapılması durumlarında uygulamanın performansında düşüş yaşanabilmektedir. Bu sebeple multithreading kullanmak, uygulamanın daha hızlı ve verimli çalışmasına olanak sağlar.
Özellikle mobil uygulamaların kullanıcı deneyimini artırmak için çoklu işlemci kullanılması önemlidir. Kullanıcılar, hızlı ve sorunsuz bir deneyim beklerler ve multithreading ile bu beklentiler karşılanabilir. Ayrıca, bu yöntem sayesinde uygulamaların daha az enerji harcaması ve daha uzun batarya ömrüne sahip olması da mümkündür.
Dispatch Queues
Dispatch Queues Nedir?
Dispatch Queues, iOS uygulama geliştirme sürecinde kullanılan Grand Central Dispatch (GCD) çerçevesi içinde yer alan bir yapıdır. GCD, iş parçacıkları kullanarak uygulamalarda multithreading işlemlerini kolaylaştıran bir çerçevedir.
Dispatch Queues, paralel işlemleri işlemek için kullanılır ve GCD'nin özelliklerini kullanarak, uygulamaların performansını artırmak ve hataları en aza indirmek için tasarlanmıştır. Bu yapı sayesinde, birden fazla işlemi aynı anda, farklı iş parçacıkları üzerinde yürütebilirsiniz.
Serial ve Concurrent Queue olmak üzere iki tür Dispatch Queue vardır. Serial Queue, işlemleri belirli bir sıraya göre yürüten bir yapıdır ve bir işlem diğerinin bitmesini bekler. Concurrent Queue ise işlemleri eşzamanlı olarak yürüten bir yapıdır ve bir işlem diğerinin bitmesini beklemez. Concurrent Queue, iş parçacıklarının birbirine müdahale etmeden çalıştığı bir ortam yaratan en popüler yapıdır.
Dispatch Queues kullanırken, bir iş parçacığındaki işlemleri çok sayıda Dispatch Queue kullanarak paralel olarak yönetebilirsiniz. İşlemler bitirildikçe, Dispatch Queue'den sırayla çıkartılırlar.
Serial Queue
Serial Queue, bir işlemi bitirmeden diğer bir işleme geçmeyen, belirli bir sıraya göre işlem yapan bir yapılı Queue'dur. Bu durumda, bir önceki işlem, sonraki işlemin bitmesini bekler ve her bir işlem sırayla yürütülür.
Bu yapıya örnek olarak, ilk gelen verinin işlenmesiyle oluşan bir sıralama işlemi düşünülebilir. Veriler sırayla işleme girer ve her bir verinin işlenmesi tamamlanmadan diğer veriye geçilmeyerek, sıranın önemli olduğu durumlarda kullanılabilir.
Serial Queue yapısı, yüksek performans gerektiren işlem senaryolarında kullanılmaz. Bunun yerine, az sayıda işlem yapması gereken durumlarda ve sırayla işlem yapılmak istendiğinde kullanılabilir.
Özetle, Serial Queue yapısı, belirli bir sıraya göre işlem yaparken, bir işlem diğerinin bitmesini bekleyerek işlemleri sırayla yaptırır.
Concurrent Queue
Concurrent Queue, bir diğer adıyla paralel kuyruk, işlemleri aynı anda yürüten bir yapıdır. Bu sayede bir işlem diğerinden bağımsız olarak devam edebilir ve diğer işlemlerin bitmesini beklemez. Bu, uygulamalarımızın daha hızlı ve düzgün çalışmasını sağlar.
Bir Concurrent Queue oluşturmak için dispatch_queue_create fonksiyonu kullanılır. Örneğin;
dispatch_queue_create fonksiyonu |
---|
dispatch_queue_t queue = dispatch_queue_create("com.example.myQueue", DISPATCH_QUEUE_CONCURRENT); |
Bu kod parçası, "com.example.myQueue" adında bir Concurrent Queue oluşturur. İşlemler sırayla yürütülmek yerine eşzamanlı olarak gerçekleştirilir.
Bir başka örnek ise aşağıdaki şekildedir;
Görev ekleme - Concurrent Queue |
---|
dispatch_async(queue, ^{ // İşlemler burada gerçekleştirilir NSLog(@"İşlem 1"); NSLog(@"İşlem 2"); NSLog(@"İşlem 3"); }); |
Bu kod parçası, önceden oluşturulan Concurrent Queue'ya üç tane işlem ekler. Bu işlemler aynı anda çalıştırılacak olan, birbirinden bağımsız işlemlerdir ve diğer işlemlerin bitmesini beklemeksizin gerçekleştirilirler.
Concurrent Queue'lar, CPU yoğunluğu yüksek uygulamalarda oldukça faydalıdır. Fakat, birçok eşzamanlı işlem, bellek tüketimini de arttırabilir. Bu nedenle, işlem sayısını kontrol altında tutmak çok önemlidir.
Block Yapısı
Objective-C programlama dilinde, bir işlemi kaplayan ve başka bir işlemi tetikleyebilen kod bloklarıdır. Bu yapının en büyük avantajı, işlemleri daha modüler bir şekilde yönetebilme olanağı sunmasıdır. Blokları, diğer fonksiyonların parametresi olarak da kullanabilirsiniz.
Bloklar, adını verdikleri işlemin belirli bir kısmını kaplayan yapılardır ve istenilen zamanda tetiklenebilirler. Bir işlemi blok içine yazarsanız, o bloğun bitişinden sonra diğer işlemler aktif hale gelebilir. Bu sayede, kullanıcının arayüzünü kilitlenmeden kullanabileceği uygulamalar yazmak mümkün hale gelir.
Eşzamanlı Programlama Nedir?
Eşzamanlı programlama, bir programda birden fazla işlemi aynı anda yürüterek daha hızlı ve verimli bir çalışma sağlayan bir programlama yöntemidir. Bu yöntem sayesinde, bir işlem diğerinin bitmesini beklemek zorunda kalmadan aynı anda birden fazla işlem yapılabilir. iOS uygulamalarında özellikle bu yöntem sıklıkla kullanılır.
Eşzamanlı programlama ile daha hızlı ve verimli işlemler yapılabilse de, bu yöntemin kullanımı bazı zorluklar da beraberinde getirir. Örneğin, aynı anda erişilen verilerin senkronize edilmesi gereklidir. Bu nedenle, eşzamanlı programlama ile çalışırken "thread safety" gibi konulara dikkat etmek önemlidir.
Thread Safety
Thread Safety, multithreading işlemleri yaparken karşılaşılan en önemli konulardan biridir. Birden fazla işlem aynı anda çalıştığı için aynı veriye erişebilirler ve bu da hatalara yol açabilir. Ancak, Thread Safety önlemleri alınarak bu hatalar engellenebilir.
Thread Safety sağlamak için genellikle kilit mekanizmaları kullanılır. Bu mekanizmalar sayesinde, herhangi bir işlem veriye erişirken diğer işlemler tarafından bloke edilir. Böylece, her işlem kendi sırasında veriye erişebilir ve çakışmalar önlenmiş olur.
Bunun yanı sıra, Thread Safety için farklı yöntemler de kullanılabilir. Örneğin, verilerin kopyaları oluşturulabilir ve her işlem kendi kopyasını kullanarak veriye erişebilir. Bu, verilerin değiştirilmesini önleyerek hataların önüne geçilmesini sağlar.
Thread Safety alınması, uygulamaların güvenliği ve performansı açısından oldukça önemlidir. Bu nedenle, multithreading işlemleri yaparken dikkatli olmak ve Thread Safety önlemlerini almak gerekmektedir.
Lock ve Unlock Fonksiyonları
Lock ve Unlock fonksiyonları, multithread uygulamalarda verilere aynı anda erişimlerin önüne geçmek için kullanılan fonksiyonlardır. Bu fonksiyonlar sayesinde, bir işlem belirli bir veriye eriştiğinde onu diğer işlemlerin erişimine kapatabiliriz. Böylece diğer işlemler bu veriye erişim yaparken hata almazlar.
Lock ve Unlock fonksiyonları, genellikle kilitli bir blok halinde kullanılırlar. Kilitli blok, uygulama içerisinde birden fazla işlemi çalıştırabileceğiniz anahtarlı bir alandır. Bu anahtarlı alanın kilidini açıp kapatarak, işlemlerin verilere erişimini kontrol edebilirsiniz.
Bir örnek verecek olursak, bir uygulamada bir dosyaya yazarken, birden fazla işlem aynı anda bu dosyaya yazmaya çalışabilir. Bu durumda dosyanın tutulduğu yerde bir Lock fonksiyonu kullanarak, dosyaya erişimi kapatmanız gerekir. Dosya işlemi bittiğinde de Unlock fonksiyonu ile erişimi tekrar açmanız gerekmektedir.
Lock ve Unlock fonksiyonları, uygulamanın performansını artırmak için önemlidir. Bu sayede, multithread uygulamalarında verilere erişim sırasında oluşabilecek hataların önüne geçebilirsiniz.
UI Thread
UI Thread, yani kullanıcı arayüzü iş parçacığı, uygulamanın kullanıcı ile etkileşim halinde olduğu zamandaki işlemleri yürüten temel iş parçacığıdır. Örneğin, bir butona tıklandığında veya bir metin kutusu doldurulduğunda kullanıcı arayüzü ile ilgili bütün işlemler UI Thread üzerinde gerçekleştirilir.
UI Thread'in çalışma mekaniği oldukça önemlidir. Eğer UI Thread üzerinde ağır işlemler yapılırsa, uygulama kullanıcıya yavaş ya da donma problemleri yaşatabilir. Bu nedenle, UI Thread her zaman en hızlı ve en akıcı şekilde çalışmalıdır.
Main Queue, UI Thread'in çalıştığı iş parçacığıdır. Bu iş parçacığı, kullanıcı arayüzü ile doğrudan etkileşim halindeki bütün işlemleri yürütür. Main Queue üzerindeki işlemler öncelikli olarak öncelik sırasına göre yürütülür.
Perform Selector On Main Thread, bir işlemin Main Queue üzerinde yapılmasını sağlayan bir yöntemdir. Bu yöntem kullanarak, bir işlemi UI Thread üzerinde yapabilir ve uygulamanın akıcılığından ödün vermeden işlem yapabilirsiniz.
Main Queue
İOS uygulamalarının arayüzlerindeki değişiklikleri gerçekleştirmek zaman alıcı bir işlemdir ve kullanıcının uygulama ile etkileşimi sırasında her zaman bir bekleme süresi oluşabilir. Ancak, Main Queue, kullanıcı arayüzü işlemlerinin yapıldığı bir iş parçacığıdır ve bu kuyruktaki işlemler UI Thread üzerinde gerçekleştirilir. Bu sayede, uygulama arayüzü ile etkileşim sorunsuz bir şekilde yapılır ve kullanıcı için akıcı bir deneyim sunulur.
UI Thread işlemlerini yaparken, Main Queue kullanımı önemlidir. UI Thread'in yüksek öncelikli işlerini yapması gerektiğinde, Main Queue üzerinde bir işlem yürütülebilir. PerformSelectorOnMainThread() fonksiyonu kullanılarak belirli bir işlem, Main Queue üzerinde çalışacak şekilde planlanabilir. Main Queue, Dispatch Queues ile aynı fikrin temelidir ancak sadece UI Thread işlemleri için kullanılır.
UI Thread içindeki işlemleri uygulamanın aldığı kullanıcının etkileşimleri doğrultusunda yönettiği için, programlamacının kod yazarken Thread Safety'yi göz önünde bulundurması önemlidir. Main Queue, UI Thread için reserved bir Queue olduğundan, programcıların Main Queue içindeki verilere aynı anda birden fazla işlem tarafından erişilmesinden kaçınmaları gerekmektedir. Bunun için, Lock ve Unlock fonksiyonları kullanılabilir.
Perform Selector On Main Thread
Perform Selector On Main Thread, uygulamamızda kullanıcının arayüzü üzerinde gerçekleştirilen işlemlerin Main Queue üzerinde yapılmasını sağlayan bir yöntemdir. Bu yöntem ile uygulamamızdaki öğelerin görünümü daha hızlı ve akıcı hale getirilebilir. PerformSelectorOnMainThread yöntemi, UI Thread üzerinde çalıştığı için UI işlemleri burada yapılabilir. Bu yöntemi kullanarak, arka planda yapılan işlemlerin sonucunu kullanıcı arayüzünde göstermek mümkündür.
Yöntemi kullanmak için belirtilen bir metodu Main Thread üzerinde gerçekleştireceğimiz öğenin üzerinde çağırmalıyız. Örneğin, viewWillAppear fonksiyonu Main Thread üzerinde işletilecek bir metot içermelidir.
Örnek olarak, aşağıdaki tabloda yer alan kodda, basit bir performSelectorOnMainThread kullanımı gösterilmektedir:
Method | Description |
performSelectorOnMainThread:withObject:waitUntilDone: | Belirtilen selector'ın Main Thread üzerinde çağırılmasını sağlar. |
Yukarıdaki örnekte, performSelectorOnMainThread yöntemi, imageLoaded metodu çağrılarak kullanıcının arayüzünde bir resim göstermek için kullanılmıştır. Bu yöntem sayesinde, arka planda yüklenen resmin kullanıcıya hemen gösterilmesi sağlanmıştır.
Bu nedenle, Perform Selector On Main Thread yöntemi çok önemlidir ve UIThread'in kalitesini artırmak için uygulamalarda kullanılmalıdır.
Dispatch vs. Operation
Dispatch Queues ve NSOperationQueue, iOS uygulamalarında multithreading işlemleri yapmak için kullanılan iki popüler yöntemdir. Dispatch Queues, Grand Central Dispatch (GCD) çerçevesi içinde yer alan yapılar arasında en temel ve kullanımı en kolay olanıdır. Concurrent Queue ve Serial Queue yapıları ile bir işlem belirli bir sıraya göre veya eşzamanlı olarak yürütülebilir. Bu yöntem, kodun okunabilirliğini ve anlaşılabilirliğini artırmak için daha fazla blok yapısının kullanılmasına ihtiyaç duyar.
NSOperationQueue, GCD üzerinde inşa edilen ancak daha yüksek seviye bir araçtır. NSOperationQueue, Grand Central Dispatch'in daha yüksek bir soyutlamasıdır ve benzer şekilde Serial Queue ve Concurrent Queue yapılarına sahiptir. Ancak, daha fazla kontrol sağlama avantajına sahip olan bu yöntem, kodun daha düzenli ve okunabilir olmasını sağlar. İşlemler bir operasyon nesnesi aracılığıyla başlatılır ve öncelikleri ayarlanarak yönetilir.