2012-03-19 16 views
12

NSCutableArray'ın ARC'yi kullanmak üzere yapılandırılan bir projede bağlantılı bellek sızıntıları yaşıyorum ve bunun sizin için bunları halledeceğini düşündüm.ARC bellek sızıntıları

Aşağıdaki kod NSNumbers sızıntılarını tetikliyor:

NSMutableArray *myArray = [[NSMutableArray alloc] init]; 

NSNumber *myNumber = [NSNumber numberWithFloat:10]; 

[myArray addObject:myNumber]; 

son satırı Running verir ayıklayıcısında aşağıdaki:

objc [1106]: Sınıf __NSCFNumber nesne 0x765ffe0 hiçbir ile autoreleased yerde havuz - sadece sızıntı yapmak - nesc_autoreleaseNoPool() üzerinde hata ayıklamak için( )

Bunun dışında, c mutant diziye doğru eklenir,

Yanlış bir şey yapıyorum mu?

Not: Projede ARC ile çalışamayacağım bir sınıf var ve bu yüzden derleyici bayrağı -fno-objc-arc kullanarak ARC'den çıkardım. Ancak, ARC kullanan diğer sınıflarda sızıntılar meydana geliyor. Bunun ilgili olup olmadığından emin değilim.

Yardımlarınız için çok teşekkürler.

+0

bu kod ayrı bir iş parçacığı üzerinde çalıştırmak ediliyor mu? Veya "@ autoreleasepool" içeriğinin dışındaki ana yöntemde mi? –

+0

Projedeki @autoreleasepool'un tek sözü ana hattır. Sorun kodu diğer sınıflarda. Yöntemin ayrı bir iş parçacığında olup olmadığını nasıl kontrol edebilirim? Ben bilerek ayrı bir iş parçacığı üzerine koymadım ama gerçekleşmiş olabilir. Projeyi, çevrimiçi olarak bulduğum ses ünitelerini kullanan resmi olmayan örnek kodlara dayanarak yaptım, bu yüzden tüm öğelerden emin değilim. – Spinoxa

+0

Merhaba Richard, Sızıntılar, arkasından hariç tutulan sınıf olan Ses Birimi'ni oluşturan aynı iş parçacığı üzerinde, ana olarak ayrı bir iş parçacığında ortaya çıkıyor. İşlemi ana konuya yeniden yönlendirebilmemin bir yolu var mı? Yoksa Ses Ünitesinin ARC ile çalışmasını sağlamak için tekrar denemeliyim? Yardımınız için çok teşekkürler, sanırım olası sebebi işaret ettiniz! – Spinoxa

cevap

39

Muhtemelen bu kodu arka plan iş parçacığında çalıştırıyorsunuz ve otoparka havuzu yok. ARC hala sizin için nesneleri otomatik olarak otomatize edecektir ve eğer Apple framework'lerine çağrı yapıyorsanız, hala ARC olmayabilirler, bu yüzden kesinlikle sizin için nesneleri otomatikleştirebilir. Yani hala bir otomatikleştirme havuzuna ihtiyacınız var.

Kakao, ana iş parçacığında sizin için bir otomatikleştirme havuzu oluşturur, ancak arka plan iş parçacıkları üzerinde sizin için hiçbir şey yapmaz. Eğer NSOperation falan kullanmadan bir arka plan iş parçacığı üzerine bir şeyler başlaması için gidiyoruz, bunu gibi bir @autoreleasepool bu konu sarmak istersiniz:

- (void)doSomething { 
    [self performSelectorInBackground:@selector(backgroundSomething)]; 
} 

- (void)backgroundSomething { 
    @autoreleasepool { 
     NSLog(@"Here I am in the background, doing something."); 
     myArray = [[NSMutableArray alloc] init]; 
     // etc. 
    } 
} 
+0

Teşekkürler, bu gerçekten sorun oldu! – Spinoxa

+0

Mükemmel, teşekkürler. Aletler Sızıntı aracı, teknik olarak sızıntı olmadıklarını sanmıyorum. – n13

+1

Kakaonun otomatik olarak otomatikleştirme havuzu oluşturmasıyla ilgili biraz kafa karıştırıcı bir ifade, "main.m" şablonunun "@autoreleasepool {" int main ('. –

-2

NSMutableArray öğesini bir statik değişken olarak tanımlamış olmanız olasıdır. Bunu yaptığınızda, herhangi bir çalıştırma havuzunun sınırları dışında kalırsınız, çünkü statik tanımlamalar herhangi bir runloop dışında aktif hale gelir. ARC sihirli değildir, sadece mevcut tutma/yayınlama çerçevesi çerçevesinde bellek yönetimi çağrılarını otomatikleştirir ve bu durumlarda yardımcı olamaz.

Çözüm, bir değişkeni dizinin runloop içinde oluşturulacağı şekilde, bir sınıftaki statik değişkeni başlangıç ​​durumuna getirmektir.

+0

Hayır, statik değişkenler bellek sızıntılarına neden olmazlarsa, mevcut projemde bunların çoğuna sahip olurdum, sadece bir @autoreleasepool bağlamının dışında kod yürütüyor olduğuna inanıyorum. –

+0

NSMutableArray öğesini bir statik değişken olarak tanımlamış olsaydım neye benziyordu? Dizi sınıf başlık dosyasında ve hangi özelliklerle bildirilmelidir? Teşekkürler – Spinoxa

+0

Bellek sızıntısı değil. En azından çoğu insan tanımlamaz. Bir autorelease bağlamının dışında kod yürütmek için pratikte karşılaştığım hemen hemen tek yol, statik bir değişkende bir NSObject bildirmektir - biliyorum, bu tam iletinin, global bir statik değişkende imageNamed ile statik bir UIImage olduğunu bildirmesi. –