NSDefaultRunLoopMode vs NSRunLoopCommonModes


114

Arkasından büyük bir dosya veya başka bir şey indirmeye çalıştığımda UIScrollView, MPMapViewiPhone ekranına dokunduğum anda indirme işlemi durduruluyor. Neyse ki, Jörn'ün harika bir blog yazısı , NSRunLoopCommonModesbağlantı için alternatif bir seçenek öneriyor .

Bu, NSDefaultRunLoopMode ve NSRunLoopCommonModes olmak üzere iki modun ayrıntılarına bakmamı sağlıyor, ancak elma belgesi, şunu söylemek dışında nazikçe açıklamıyor

NSDefaultRunLoopMode

NSConnection nesneleri dışındaki giriş kaynakları ile ilgilenme modu. Bu, en yaygın olarak kullanılan çalışma döngüsü modudur.

NSRunLoopCommonModes

Mod olarak bu değer kullanılarak bir çalışma döngüsüne eklenen nesneler, "ortak" modlar kümesinin bir üyesi olarak bildirilen tüm çalışma döngüsü modları tarafından izlenir; ayrıntılar için CFRunLoopAddCommonMode açıklamasına bakın.

CFRunLoopAddCommonMode

Kaynaklar, zamanlayıcılar ve gözlemciler bir veya daha fazla çalışma döngüsü moduna kaydedilir ve yalnızca çalışma döngüsü bu modlardan birinde çalışırken çalışır. Ortak modlar, bu modlar tarafından paylaşılan bir dizi kaynak, zamanlayıcı ve gözlemci tanımlayabileceğiniz bir dizi çalışma döngüsü modudur. Örneğin, her bir spesifik çalışma döngüsü modu için bir kaynak kaydetmek yerine, onu çalışma döngüsünün ortak sözde moduna bir kez kaydedebilirsiniz ve ortak mod setindeki her çalışma döngüsü modunda otomatik olarak kaydedilir. Benzer şekilde, ortak kipler kümesine bir kip eklendiğinde, ortak sözde kipe halihazırda kayıtlı olan herhangi bir kaynak, zamanlayıcı veya gözlemci yeni eklenen ortak kipe eklenir.

Lütfen kimse ikisini insan dilinde açıklayabilir mi?

Yanıtlar:


204

Bir çalışma döngüsü, sistemin eşzamansız olayları yönetebilmeleri için uyku iş parçacıklarını uyandırmasına izin veren bir mekanizmadır. Normalde bir iş parçacığı çalıştırdığınızda (ana iş parçacığı haricinde) iş parçacığını bir çalışma döngüsünde başlatıp başlatmama seçeneği vardır. İş parçacığı, harici olaylarla etkileşim olmadan ve zamanlayıcılar olmadan bir tür veya uzun süreli işlem çalıştırırsa, bir çalışma döngüsüne ihtiyacınız yoktur, ancak iş parçacığınızın gelen olaylara yanıt vermesi gerekiyorsa, bir çalışma döngüsüne eklenmelidir. yeni olaylar geldiğinde ileti dizisini uyandırın. Durum buNSURLConnection yalnızca gelen olaylarda (ağdan) uyandıkları için oluşturulan iş parçacıkları .

Her iş parçacığı, birden çok çalıştırma döngüsüyle ilişkilendirilebilir veya farklı modlarda çalışmak üzere ayarlanabilen belirli bir çalıştırma döngüsüyle ilişkilendirilebilir. "Çalıştırma döngüsü modu", işletim sistemi tarafından belirli olayların ne zaman teslim edileceğine veya daha sonra teslim edilmek üzere toplanacağına ilişkin bazı kurallar oluşturmak için kullanılan bir konvansiyondur.

Genellikle tüm çalıştırma döngüleri, girdi olaylarını yönetmek için varsayılan bir yol oluşturan "varsayılan moda" ayarlanır. Örneğin: bir fareyle sürükleme (Mac OS) veya dokunma (iOS'ta) olayı gerçekleşir gerçekleşmez bu çalıştırma döngüsünün modu olay izleme olarak ayarlanır; bu, iş parçacığının yeni ağ olaylarında uyandırılmayacağı, ancak bu olayların daha sonra kullanıcı giriş olayı sona erdiğinde ve çalıştırma döngüsü tekrar varsayılan moda ayarlandığında teslim edileceği anlamına gelir; Açıkçası bu, işletim sistemi mimarları tarafından arka plan olayları yerine kullanıcı olaylarına öncelik vermek için yapılan bir seçimdir.

İş NSURLConnectionparçacığınız için çalıştırma döngüsü modunu kullanarak değiştirmeye karar verirseniz scheduleInRunLoop:forModes:, iş parçacığını belirli varsayılan çalıştırma döngüsü yerine özel bir çalıştırma döngüsü moduna atayabilirsiniz . Çağrılan özel sözde mod NSRunLoopCommonModes, olay izleme dahil birçok girdi kaynağı tarafından kullanılır. Örneğin, NSURLConnectionörneğini ortak moda atamak , olaylarını "varsayılan moda" ek olarak "izleme modu" ile ilişkilendirmek anlamına gelir. Konuları ilişkilendirmenin bir avantajı / dezavantajıNSRunLoopCommonModes , iş parçacığının dokunma olayları tarafından engellenmemesidir.

Ortak modlara yeni modlar eklenebilir, ancak bu oldukça düşük seviyeli bir işlemdir.

Birkaç not ekleyerek kapatmak istiyorum:

  • Tipik olarak bir tablo görünümüyle ağdan indirilen bir dizi resim veya küçük resim kullanmamız gerekir. Tablo görünümü kaydırılırken bu görüntüleri ağdan indirmenin kullanıcı deneyimini iyileştirebileceğini düşünebiliriz (çünkü kaydırma sırasında görüntüleri görebiliyorduk), ancak kaydırmanın akışkanlığı büyük ölçüde zarar görebileceğinden bu avantajlı değildir. Bu örnekte NSURLConnectionbir çalıştırma döngüsü kullanılmamalıdır; UIScrollViewkaydırmanın ne zaman sonlandırıldığını tespit etmek için temsilci yöntemlerini kullanmak ve ardından tabloyu güncellemek ve ağdan yeni öğeler indirmek daha iyi olacaktır ;

  • Kodunuzu çalıştırma döngüsü yönetimi sorunlarından "korumanıza" yardımcı olacak GCD kullanmayı düşünebilirsiniz. Yukarıdaki örnekte, ağ isteklerinizi özel bir seri kuyruğa eklemeyi düşünebilirsiniz.


9
Sevgili Viggio24, bu temiz ve kesin açıklama için çok teşekkür ederim. Apple'dan yorumunuzu API kılavuzlarına eklemesini isterim. ;)
Stkim1

7
viggio24'ün yanıtı mükemmel. İlgilenenler için şunu belirtmek isterim için WWDC 2010'dan Oturum 208'in (iPhone OS için Ağ Uygulamaları, Bölüm 2) çalıştırma döngüleri hakkında bir giriş içerdiğini . Eğer ilgileniyorsanız bir göz atın. Umarım yardımcı olur.
Lorenzo B

19
Sadece kendim için bir not: NSRunLoopCommonModesiçeri kaydırırken zamanlayıcı olayına izin verir UIScrollView.NSDefaultRunLoopModekaydırma sırasında zamanlayıcıyı engelleyin.
eonil

2
Çok zorlu bir konudan bahsettiği için kaydırma görünümü güncellemesiyle ilgili yorumu çok ilginç buldum. Bununla ilgili daha fazla ayrıntı eklemek için: Bir NSURLC bağlantısı için bir mod ayarladığınızda, bu yalnızca delege geri aramalarının yürütülmesini etkiler. Burada scrollView'i güncellemenin bir performans sorununa neden olabileceğini anlıyorum, ancak bu neden oluyor? Cevap, resmin belleğe yüklenmesi gerektiğiyse, bunu arka planda bir grafik bağlamına yazarak yapabilir ve bunu yaptıktan sonra görünüm ana katmanınızı güncelleyebilirsiniz. bu mantıklı geliyor mu?
nebillo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.