Otomatik yayın havuzunu bir Swift programında kullanmak gerekli midir?


97

Bu WWDC14 sunumunun 17. sayfasında şöyle yazıyor:

Objective-C ile mi çalışıyorsunuz? Yine de otomatik yayın havuzları otomatik yayın havuzunu
{/ * kod * /} yönetmeniz gerekiyor

Bu ne anlama geliyor? Bu, kod tabanımda herhangi bir Objective-C dosyası yoksa autoreleasepool {}gereksiz olduğu anlamına mı geliyor ?

In ilgili sorunun cevabını , bir örnek vardır autoreleasepoolyararlı olabilir:

- (void)useALoadOfNumbers {
    for (int j = 0; j < 10000; ++j) {
        @autoreleasepool {
            for (int i = 0; i < 10000; ++i) {
                NSNumber *number = [NSNumber numberWithInt:(i+j)];
                NSLog(@"number = %p", number);
            }
        }
    }
}

Yukarıdaki kod autoreleasepoolbırakılarak Swift'e çevrilirse, Swift numberdeğişkenin ilkinden sonra serbest bırakılması gerektiğini bilecek kadar akıllı olacak mı }(diğer bazı dillerde olduğu gibi)?


1
Swift'de herhangi bir belge yok gibi görünüyor autoreleasepool. Ben senin soru üzerine genişletilmiş ve dev forumlarda bunu istedi .
Aaron Brager

Yanıtlar:


199

autoreleasepoolDöndürürken desen Swift kullanılmaktadır autorelease(sizin Objective-C kodu veya Kakao sınıflarını kullanarak ya oluşturulan) nesneleri. autoreleaseÇok böyle Swift işlevlerde desen Objective-C yok. Örneğin, yönteminizin bu Swift yorumunu düşünün (örnekleme NSImage/ UIImagenesneler):

func useManyImages() {
    let filename = pathForResourceInBundle

    for _ in 0 ..< 5 {
        autoreleasepool {
            for _ in 0 ..< 1000 {
                let image = NSImage(contentsOfFile: filename)
            }
        }
    }
}

Bunu Araçlar'da çalıştırırsanız, aşağıdaki gibi bir tahsis grafiği görürsünüz:

otomatik yayın havuzu ile

Ancak bunu otomatik yayın havuzu olmadan yaparsanız, en yüksek bellek kullanımının daha yüksek olduğunu göreceksiniz:

otomatik yayın havuzu olmadan

Bu autoreleasepool, tıpkı Objective-C'de olduğu gibi Swift'de otomatik serbest bırakma nesnelerinin ne zaman serbest bırakıldığını açıkça yönetmenizi sağlar.

Not: Swift yerel nesneleriyle uğraşırken, genellikle otomatik serbest bırakma nesneleri almazsınız. Bu nedenle sunumda, Apple'ın bu noktada daha net olmasını diliyorum, ancak "Objective-C ile çalışırken" buna ihtiyaç duyulduğundan bahsetti. Ancak, Objective-C nesneleriyle (Cocoa sınıfları dahil) uğraşıyorsanız, bunlar otomatik olarak serbest bırakılan nesneler olabilir; bu durumda, Objective-C @autoreleasepoolmodelinin bu Swift yorumu yine de yararlıdır.


2
Tüm bu sorularda, kendi sınıfınızı yazabilir ve bir printlngiriş yapmasını sağlayabilirsiniz deinitve nesnelerin ayrılmasının tam olarak ne zaman yapıldığını doğrulamak oldukça kolay hale gelir. Veya Aletler'de gözlemleyin. Sorunuza yanıt olarak, Swift nesnelerinin +1 tutma sayımlı (nesneleri otomatik serbest bırakma değil) işlevlerden döndürüldüğü ve arayan kişinin sahipliği bu noktadan itibaren sorunsuz bir şekilde yöneteceği (örneğin, döndürülen nesne kapsam dışına çıkarsa, hemen boşaltılır, otomatik bırakma havuzuna yerleştirilmez).
Rob

3
@StevenHernandez Bir otomatik yayın havuzunun sızıntılarla çok az ilgisi vardır. Bir sızıntı, yayınlanmamış nesneden kaynaklanıyor. Öte yandan, otomatik yayın havuzu, havuz boşaltılıncaya kadar serbest bırakmanın ertelendiği nesnelerin bir koleksiyonudur. Havuzlar bir şeyin serbest bırakılıp bırakılmayacağını kontrol etmez, daha ziyade bu tür tahsisin kaldırılmasının zamanlamasını kontrol eder. Harita görünümünü yeniden, önbelleğe almanın ne yaptığını kontrol edemezsiniz (hafızayı kullanır, ancak gerçek sızıntı yapmaz) veya gerçek bir sızıntı varsa hiçbir şey yapamazsınız (ve geçmişte olmuş olsa da önemli bir harita görünümü sızıntısının farkında değilim. UIKit'te rastgele, mütevazı sızıntılar).
Rob

2
@matt Evet, benzer davranışlar gördüm. Bu yüzden NSImage/ UIImagenesnelerle egzersizimi tekrarladım ve sorunu daha tutarlı bir şekilde ortaya koydum (ve açıkçası, bu sorunun daha yaygın bir örneğidir, çünkü en yüksek bellek kullanımı genellikle yalnızca daha büyük nesnelerle uğraşırken sorunludur; bunun pratik bir örneği olabilir bir grup görüntüyü yeniden boyutlandırma rutini). Ayrıca, otomatik yayın nesnelerini açıkça oluşturan Objective-C kodunu çağıran davranışı da yeniden ürettim. Beni yanlış anlamayın: Bence Swift'de otomatik yayın havuzlarına Objective-C'den daha az ihtiyacımız var, ancak yine de oynayacağı bir role sahip.
Rob

1
İşe yarayan bir örnek buldum! Sadece NSBundle'ı pathForResource:ofType:tekrar tekrar arayın .
matt

1
Benim pathForResource:ofType:örnek artık Xcode 6.3 / Swift 1.2 çalışır. :)
matt

5

Bunu eşdeğer Objective-C kodunda kullanırsanız, Swift'de kullanırsınız.

Swift, sayı değişkeninin ilkinden sonra serbest bırakılması gerektiğini bilecek kadar akıllı olacak}

Sadece Objective-C yaparsa. Her ikisi de Cocoa bellek yönetimi kurallarına göre çalışır.

Elbette ARC number, döngünün bu yinelemesinin sonunda kapsamın dışına çıktığını bilir ve eğer devam ederse, orada serbest bırakacaktır. Ancak, bu size nesnenin otomatik olarak yayımlanıp yayımlanmadığını söylemez, çünkü otomatik olarak yayımlanmış bir örnek döndürmüş -[NSNumber numberWithInt:] olabilir veya olmayabilir . Bilmenizin hiçbir yolu yok, çünkü kaynağına erişiminiz yok -[NSNumber numberWithInt:].


1
Swift bunun için Objective-C ile aynı şekilde davranıyorsa, neden sunumda "Objective-C ile Çalışmak" dan bahsediliyor? özellikle?
Ethan

9
@Ethan Görünüşe göre yerel Swift nesneleri otomatik olarak serbest bırakılan nesneler değildir ve autoreleasepoolyapı tamamen gereksizdir. Ancak Swift kodunuz Objective-C nesnelerini (Cocoa nesneleri dahil) işliyorsa, bunlar otomatik serbest bırakma modellerini izler ve böylece autoreleasepoolyapı yararlı hale gelir.
Rob

"Otomatik yayın havuzu, Swift'de otomatik serbest bırakma nesneleri serbest bırakıldığında açıkça yönetmenize izin verir" diye anlıyorum ama neden bunu yapmak isteyeyim? Derleyici bunu neden benim için yapmıyor / yapamıyor? Sanal makinenin, büyük bir dizi manipülasyonu döngüsünde çatıdan geçmesini önlemek için kendi otomatik yayın havuzumu eklemek zorunda kaldım. Nereye eklenmesi gerektiği benim için açıktı ve mükemmel çalıştı. Derleyici neden yapamadı? Derleyici, iyi bir iş çıkarması için daha akıllı hale getirilebilir mi?
vonlost
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.