2013-02-06 27 views
7

Temel olarak, bir NSDictionary numaralı veri kümem var, ancak kolaylık sağlamak için birkaç farklı şekilde sıralanmış ve filtrelenmiş verilerle NSArray s ayarlıyorum. Veriler farklı iş parçacıkları (bloklar) ile geliyor olacak ve veri mağazamı değiştirerek bir kerede sadece bir blok olduğundan emin olmak istiyorum.Senkronize blok ve GCD'ye karşı dispatch_async()

Bu öğleden sonra bir gönderi kuyruğu kurma zahmetinden geçtim ve ardından rastgele bir şekilde, tam olarak ne yapmak istediğimi hemen hemen tam olarak gösteren @synchronized ile ilgili bir yazıya rastladım.

Yani şu anda ne ...

// a property on my object 
@property (assign) dispatch_queue_t matchSortingQueue; 

// in my object init 
_sortingQueue = dispatch_queue_create("com.asdf.matchSortingQueue", NULL); 

// then later... 
- (void)sortArrayIntoLocalStore:(NSArray*)matches 
{ 
    dispatch_async(_sortingQueue, ^{ 
     // do stuff... 
    }); 
} 

Ve benim sorum, ben sadece aşağıdaki tüm bu yerini alabilir edilir?

- (void)sortArrayIntoLocalStore:(NSArray*)matches 
{ 
    @synchronized (self) { 
     // do stuff... 
    }; 
} 

... Ve yine ikisi arasındaki fark nedir? Ne düşünmeliyim?

+0

'@ synchronized' gerçekten yavaş. Şu anda aradığım metrikleri bulamıyorum, ayrıca https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html adresini de kontrol edemiyorum. – Richard

+0

Verileriniz aynı gönderim kuyruğu (aynı iş parçacığı) üzerinden geliyorsa, çarpışmayacaktır. Farklı kuyruklar (farklı iş parçacıkları) kullanacaksanız, senkronizasyon gerekli olacaktır. – Jeremy

+0

Bulunan (http://stackoverflow.com/q/10094361/480850 yoluyla) o: http://perpendiculo.us/?p=133 – Richard

cevap

5

İşlevsel fark sizin için önemli olmayabilir, ancak beklediğiniz şey: @synchronize ise, işlediğiniz konu özel yürütme yapana kadar engellenir. Bir seri gönderme sırasına eşzamansız olarak gönderirseniz, çağıran iş parçacığı başka şeylerle baş edebilir ve aslında her ne yapıyorsanız yapın, her zaman aynı, bilinen sıra üzerinde gerçekleşir.

Böylece üçüncü bir kaynak aynı anda sadece bir kuyruktan kullanılır sağlamaktan eşdeğerdir. diyelim ki, ana kuyruktan kullanıcı arayüzü tarafından erişilen bir kaynak vardı ve bunu mutasyona istedim eğer

Sevk daha iyi bir fikir olabilir. Daha sonra kullanıcı arabirim kodunuz @synchronize'a açıkça ihtiyaç duymaz, bu da iş parçacığınızın karmaşıklığını doğal olarak nesnenin içinde gizler. Eğer farklı bir aktörde bu değişikliklerin birçoğunu tetikleyebilecek merkezi bir aktörünüz varsa, sevk daha iyi bir fikir olacaktır. Bu, aynı anda çalışmasına izin verecek.

Senkronizasyon daha küçük boyutludur ve hata ayıklama adımı çok daha kolaydır. Yaptığınız şey iki ya da üç çizgi olma eğilimindeyse ve zaman zaman eşzamanlı olarak göndermeniz gerekiyorsa, o zaman bir kuyruk yaratma çabasına gitme gibi hissettiriyor - buna değer yaratmanın örtük maliyetlerini düşünürseniz bir blok ve yığının üzerine taşınıyor.

+0

Ayrıntılı yanıt için teşekkürler.Async kuyruğu istediğim şey gibi geliyor. – livingtech

4

İkinci durumda, "işlerin yapılması" yapılıncaya kadar arama iş parçacığını engellersiniz. Sıraları ve dispatch_async kullanarak arama iş parçacığını engellemezsiniz. Bu, UI dizisinden sortArrayIntoLocalStore çağırırsanız özellikle önemlidir.

İlgili konular