-RetainCount ne zaman kullanılır?


110

-retainCountŞimdiye kadar hangi durumda kullandınız ve nihayetinde onu kullanarak ortaya çıkabilecek sorunları bilmek isterim .

Teşekkürler.


5
yapmanız gerekir asla kullanıcı -retainCount.
holex

3
(Yapmanız gereken zamanlar hariç. Neler olup bittiğini anlamanıza yardımcı olmak çok nadiren yararlıdır, ancak zaman zaman ciddi şekilde yanıltıcı olabileceğini anladığınız sürece. Ve tabii ki ARC kullanılıyorsa buna hiç izin verilmez.)
Hot Licks

Yanıtlar:


243

Asla kullanmamalısın -retainCount, çünkü sana asla yararlı bir şey söylemiyor. Foundation ve AppKit / UIKit çerçevelerinin uygulanması opaktır; neyin alıkonulduğunu, neden saklandığını, kimin elinde tuttuğunu, ne zaman saklandığını vb. bilmiyorsunuz.

Örneğin:

  • Bunu düşünmek istiyorum [NSNumber numberWithInt:1]bir olurdu retainCount1 olarak Gelmez. 2.
  • Bunu düşünmek istiyorum @"Foo"bir olurdu retainCount1 olarak Gelmez. 1152921504606846975.
  • Bunu düşünmek istiyorum [NSString stringWithString:@"Foo"]bir olurdu retainCount1 olarak Gelmez. Yine 1152921504606846975.

Temel olarak, herhangi bir şey bir nesneyi tutabileceğinden (ve dolayısıyla onu değiştirebileceğinden retainCount) ve bir uygulamayı çalıştıran kodun çoğunun kaynağına sahip olmadığınız için, bir nesneninki retainCountanlamsızdır.

Bir nesnenin neden ayrılmadığını bulmaya çalışıyorsanız, Aletler'deki Sızıntılar aracını kullanın. Bir nesnenin neden çok erken ayrılmasının izini sürmeye çalışıyorsanız, Instruments'daki Zombies aracını kullanın.

Ama kullanmayın -retainCount. Gerçekten değersiz bir yöntem.

Düzenle

Lütfen herkes http://bugreport.apple.com adresine gidin ve -retainCountkullanımdan kaldırılmasını isteyin . Ne kadar çok insan bunu isterse o kadar iyi.

düzenle # 2

Güncelleme olarak, [NSNumber numberWithInt:1]şimdi retainCount9223372036854775807'ye sahip . Kodunuz 2 olmasını bekliyorsa, kodunuz artık bozulmuştur.


4
Örnekleriniz için @ Dave-Delong'a teşekkürler.
Moszi

1
KeepCount şu anda singletonlar için kullanışlıdır. (Şimdi soru, singletonların ne kadar yararlı olduğudur ...) - (NSUInteger)retainCount{return NSUIntegerMax;}.
Joe

8
@Joe, geçersiz kılmadan bir singleton yapabilirsiniz retainCount.
Dave DeLong

5
@Joe Bunun farkındayım; Bu örneğin neden pek iyi olmadığına dair tüm tartışmalar için Google "hedef-c singleton".
Dave DeLong

2
Kullandığım bir şey - @ DaveDeLong, bunu da yanlış bulabilirsin, ama ben öyle düşünmüyorum - dealloc'ların ve başlangıçların üzerine yazmak ve NSLog'ları onlara (ARC ile bile) koymak. Bu bana nesnelerin serbest bırakılıp bırakılmadığına dair harika bir fikir veriyor, bu genellikle yanıtlamaya çalıştığımız asıl soru ..
Dan Rosenstark

50

ASLA!

Ciddi anlamda. Sadece yapma.

Sadece izleyin Bellek Yönetimi Kuralları ve sadece ne bırakın alloc, newya da copy(ya da ne denir retainaslen üzerine).

@bbum en iyi burada SO'da ve blogunda daha ayrıntılı olarak söyledi .


8
Çünkü hafızayı saydığını düşüneceksin, ama yanlış yapacaksın.
Abizern

@Abizern - peki ya diğer cevaplardan birindeki singleton durumu?
Moszi

3
Buna ek olarak, edinebileceğiniz herhangi bir bilgi -retainCount(çok daha ayrıntılı olarak) Aletlerden ve araçlarından elde edilebilir.
Dave DeLong

3
Dave'in söylediklerine eklemek için; bir nesnenin mutlak tutma sayısı bir uygulama ayrıntısıdır. Hem nesnenin iç kısmının bir detayı hem de nesnenin içinden geçirilmiş olabileceği diğer herhangi bir nesnenin bir detayı. Arayan retain, retain, retain, autorelease, otomatik salma, autoreleaseörneğin, UIKit API aracılığıyla bir nesne geçen mükemmel geçerli sonucu olabilir.
bbum

2
@ d11wtq KeepCount ever == 0 ise, tekilliğe ulaşılmıştır!
bbum

14

Otomatik olarak yayımlanan nesneler, -retainCount denetiminin bilgilendirici olmadığı ve potansiyel olarak yanıltıcı olduğu durumlardan biridir. Saklama sayısı, bir nesnede kaç kez -otomatik sürümün çağrıldığı ve dolayısıyla mevcut otomatik serbest bırakma havuzu boşaldığında kaç kez serbest bırakılacağı hakkında size hiçbir şey söylemez.


1
Teşekkürler - bu iyi bir nokta. Bu, jenerik "yapma" nın yanı sıra, neden retCount kullanılmadığını açıklayan bir nedeni olan ilk cevaptır.
Moszi

1
@Moszi: Sorunuz "KeepCount ne zaman kullanılır?" - eğer bu soruyu sormak istemediysen, başka bir şey sormalıydın.
Chuck

@chuck - aslında "ne zaman kullanmalıyım" ile ilgilenmiştim, ancak görünen o ki her yanıt "asla" olmayacak ... Ama - sanırım haklısın. Soruyu birkaç gün açık bırakacağım ve hiçbir zaman dışında bir cevap olmayacaksa, o zaman cevap olarak "asla" ı kabul edeceğim.
Moszi

10

Ben do 'Instruments' kullanarak işaretlendiğinde çok faydalı retainCounts bulabilirsiniz.

'Tahsisler' aracını kullanarak, 'Referans sayılarını kaydet' seçeneğinin açık olduğundan emin olun ve herhangi bir nesneye girebilir ve keepCount geçmişini görebilirsiniz.

Allocs ve sürümleri eşleştirerek neler olup bittiğini iyi bir şekilde görebilir ve genellikle bir şeyin yayınlanmadığı bu zor durumları çözebilirsiniz.

Bu beni asla yarı yolda bırakmadı - iOS'un erken beta sürümlerinde hata bulma dahil.


5

NSObject'teki Apple belgelerine bir göz atın, sorunuzu hemen hemen kapsıyor: NSObject keepCount

Kısacası, kendi referans sayma sisteminizi uygulamadığınız sürece KeepCount muhtemelen sizin için işe yaramaz (ve sahip olmayacağınızı neredeyse garanti edebilirim).

Apple'ın kendi ifadesiyle, keepCount, "bellek yönetimi sorunlarının ayıklanmasında tipik olarak hiçbir değeri yoktur".


Öncelikle cevabınız için teşekkür ederim. Genellikle insanların bu soruya tepkisi "ASLA" olur. (Cevaplara bakın). Aslında "hata ayıklamada değer yok" "ASLA" anlamına gelmez. Öyleyse sorum şu - neden onu kullanmama duygusu güçlü (örneğin tekli uygulamada - yine cevaplardan biri)?
Moszi

Sanırım onu ​​ne için kullandığınız hakkında daha fazla bilgi vermeniz gerekecek. Kabul edilebilir bir kullanım, Apple tarafından önerildiği gibi, kendi referans sayma sisteminizi uygulamak için keepCount'u geçersiz kılmak olacaktır. Ama pratikte bunu asla göremezsin (Ben asla sahip olmadım). Güçlü tepki genellikle Apple'ın kendilerinin (posta gruplarında, dokümanlarda, geliştirici forumlarında vb.) KeepCount'u yalnız bırakmasını savunduğu gerçeğinden gelir.
lxt

1
@Moszi: Hata ayıklama, çoğu insanın bunun bir değeri olduğunu düşünebildiği tek durumdur, bu yüzden orada güvenilmezse, asla yararlı değildir. Başka hangi kullanımları düşünüyorsunuz?
Chuck

4

Elbette, kodunuzda retCount yöntemini asla kullanmamalısınız, çünkü değerinin anlamı nesneye kaç otomatik sürümün uygulandığına bağlıdır ve bu tahmin edemeyeceğiniz bir şeydir. Bununla birlikte, hata ayıklama için çok kullanışlıdır - özellikle ana olay döngüsünün dışındaki Appkit nesnelerinin yöntemlerini çağıran koddaki bellek sızıntılarını araştırırken - ve kullanımdan kaldırılmamalıdır.

Kendi fikrinizi belirtme çabanızda, değerin anlaşılmaz doğasını ciddiye aldınız. Her zaman bir referans sayısı olmadığı doğrudur. Bayraklar için kullanılan bazı özel değerler vardır, örneğin bir nesnenin asla ayrılmaması gerektiğini belirtmek için. 1152921504606846975 gibi bir sayı siz onaltılık olarak yazıp 0xfffffffffffffff alana kadar çok gizemli görünüyor. Ve 9223372036854775807, hex biçiminde 0x7fffffffffffffff'dir. KeepCount'u saniyede 100.000.000 kez artırdığınızı varsayarsak, daha büyük sayı kadar yüksek bir holdCount elde etmenin neredeyse 3000 yıl alacağı düşünüldüğünde, birinin bu gibi değerleri bayrak olarak kullanmayı seçmesi gerçekten şaşırtıcı değildir.


3

Kullanarak ne gibi sorunlar yaşayabilirsiniz? Tek yaptığı nesnenin saklama sayısını döndürmektir. Onu hiç aramadım ve aramam için herhangi bir sebep düşünemiyorum. Yine de ayrılmadıklarından emin olmak için tekillerde geçersiz kıldım.


2
Singleton durumunda bunu geçersiz kılmak için hiçbir sebep yoktur. Foundation / CoreFoundation'da retainCountbellek yönetimi için kullanılan hiçbir kod yolu yoktur .
bbum

Release, onu dealloc çağırıp çağırmayacağına karar vermek için kullanmıyor mu?
ughoavgfhw

2
Hayır; Keep / release / autorelease'in dahili uygulaması CoreFoundation'da derin köklere sahiptir ve gerçekten beklediğiniz gibi değildir. Git CoreFoundation kaynağını (mevcut) alın ve bir göz atın.
bbum

3

Uygulamanız çalışmaya başlayana ve faydalı bir şey yapana kadar bellek sızıntısı konusunda endişelenmemelisiniz.

Bir kez, Aletleri çalıştırın ve uygulamayı kullanın ve bellek sızıntısı gerçekten olup olmadığını görün. Çoğu durumda, bir nesneyi kendiniz yaratırsınız (böylece ona sahip olursunuz) ve işiniz bittikten sonra onu bırakmayı unuttunuz.

Kodunuzu yazarken denemeyin ve optimize etmeyin, uygulamayı normal olarak kullandığınızda neyin bellek sızıntısı olabileceğine veya çok uzun sürebileceğine dair tahminleriniz genellikle yanlıştır.

Doğru kodu deneyin ve yazın, örneğin, ayırma ve benzeri kullanarak bir nesne yaratırsanız, onu doğru şekilde serbest bıraktığınızdan emin olun.


0

Bunu asla kodunuzda kullanmamalısınız, ancak hata ayıklarken kesinlikle yardımcı olabilir


0

Kodunuzda asla -retainCount kullanmayın. Ancak kullanırsanız, sıfır döndürdüğünü asla görmezsiniz. Nedenini düşünün. :-)


0

Dave'in gönderisinde kullanılan örnekler NSNumber ve NSStrings'dir ... bu nedenle, UIViews gibi bazı diğer sınıfları kullanırsanız, eminim doğru cevabı alacaksınız (Tutma sayısı uygulamaya bağlıdır ve tahmin edilebilir).

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.