İle başlayalım retain
ve release
; autorelease
temel kavramları anladıktan sonra gerçekten özel bir durumdur.
Cocoa'da her nesne, kendisine kaç kez başvurulduğunu izler (özellikle, NSObject
temel sınıf bunu uygular). retain
Bir nesneyi çağırarak , referans sayısını bir artırmak istediğinizi söylüyorsunuz. Çağırarak release
, nesneyi bıraktığınızı söylersiniz ve referans sayısı azalır. Çağrıldıktan sonra release
referans sayısı artık sıfırsa, o nesnenin belleği sistem tarafından serbest bırakılır.
Bunun temel yoldan farklı olması malloc
ve free
herhangi bir nesnenin, kullandıkları belleği serbest bıraktığınız için sistemin diğer bölümlerinin çökmesi konusunda endişelenmesine gerek olmamasıdır. Herkesin birlikte oynadığını ve kurallara göre sakladığını / serbest bıraktığını varsayarsak, bir kod parçası nesneyi koruduğunda ve sonra serbest bıraktığında, nesneye referans veren diğer herhangi bir kod parçası da etkilenmeyecektir.
Ne bazen kafa karıştırıcı olabilir aramak edildiğini belirttiği durumunu bildiğim olduğunu retain
ve release
. Genel kuralım, bir nesneye bir süre bağlı kalmak istiyorsam (örneğin, bir sınıftaki üye değişkeni ise), nesnenin referans sayısının beni bildiğinden emin olmam gerektiğidir. Yukarıda açıklandığı gibi, bir nesnenin referans sayısı çağrı yapılarak artırılır retain
. Geleneksel olarak, nesne bir "init" yöntemiyle oluşturulduğunda da artırılır (gerçekten 1'e ayarlanır). Her iki durumda da, release
işim bittiğinde nesneyi aramak benim sorumluluğumdadır . Yapmazsam, bir hafıza sızıntısı olacak.
Nesne oluşturma örneği:
NSString* s = [[NSString alloc] init]; // Ref count is 1
[s retain]; // Ref count is 2 - silly
// to do this after init
[s release]; // Ref count is back to 1
[s release]; // Ref count is 0, object is freed
Şimdi için autorelease
. Otomatik serbest bırakma, sisteme bu nesneyi bir süre sonra serbest bırakmasını söylemenin uygun (ve bazen gerekli) bir yolu olarak kullanılır. Sıhhi tesisat açısından bakıldığında, autorelease
çağrıldığında, mevcut iş parçacığı NSAutoreleasePool
çağrı hakkında uyarılır. Artık NSAutoreleasePool
bir fırsat yakaladığında (olay döngüsünün geçerli yinelemesinden sonra) release
nesneyi çağırabileceğini biliyor . Programcılar olarak bizim bakış release
açımızdan, bizi aramaya özen gösterir , bu yüzden buna gerek yoktur (ve aslında yapmamalıyız).
Unutulmaması gereken önemli nokta, (yine geleneksel olarak) tüm nesne oluşturma sınıfı yöntemlerinin otomatik olarak yayımlanan bir nesne döndürmesidir. Örneğin, aşağıdaki örnekte, "s" değişkeninin referans sayısı 1'dir, ancak olay döngüsü tamamlandıktan sonra yok edilecektir.
NSString* s = [NSString stringWithString:@"Hello World"];
Bu dizeye takılmak istiyorsanız, retain
açıkça aramanız ve sonra release
işiniz bittiğinde açıkça aramanız gerekir .
Aşağıdaki (çok uydurulmuş) kod parçasını düşünün ve autorelease
gerekli olduğu bir durum göreceksiniz :
- (NSString*)createHelloWorldString
{
NSString* s = [[NSString alloc] initWithString:@"Hello World"];
// Now what? We want to return s, but we've upped its reference count.
// The caller shouldn't be responsible for releasing it, since we're the
// ones that created it. If we call release, however, the reference
// count will hit zero and bad memory will be returned to the caller.
// The answer is to call autorelease before returning the string. By
// explicitly calling autorelease, we pass the responsibility for
// releasing the string on to the thread's NSAutoreleasePool, which will
// happen at some later time. The consequence is that the returned string
// will still be valid for the caller of this function.
return [s autorelease];
}
Tüm bunların biraz kafa karıştırıcı olduğunun farkındayım - yine de bir noktada tıklanacak. İşte başlamanıza yardımcı olacak birkaç referans:
- Apple'ın bellek yönetimine girişi .
- Mac OS X için Cocoa Programming (4th Edition) , Aaron Hillegas - birçok harika örnek içeren çok iyi yazılmış bir kitap. Bir öğretici gibi okur.
- Gerçekten dalıyorsanız, Big Nerd Ranch'a gidebilirsiniz . Bu, yukarıda bahsedilen kitabın yazarı Aaron Hillegas tarafından işletilen bir eğitim tesisidir. Orada birkaç yıl önce Kakaoya Giriş kursuna katıldım ve bu öğrenmenin harika bir yoluydu.