Objective-C: Bir yöntemde sabitleme bellek yönetimi

oy
5

Neredeyse orada ancak aşağıdaki kodla zor günler yaşıyorum, Objective-C basit referans sayma / bellek yönetimini anlama ediyorum. Ben mutableDict bırakmadan ediyorum (aşağıda kodda yorumladı) ve bu benim kodunda zararlı davranışları neden oluyor. Ben bellek sızıntısı izin varsa, beklendiği gibi çalışır, ama bu burada açıkça cevap değil. ;-) Aranızda daha deneyimli millet nezaketini daha iyi hafızam ayak izi ele bu yöntemin herhangi yeniden yazmak nasıl olarak doğru yönde işaret etmek olurdu? Esas olarak burada büyük suçlu gibi ben NSMutableDictionary * mutableDict idare ediyorum nasıl. Sorunu anlamak ister ve sadece / yapıştır kodu kopyalayıp ediyorum - bu yüzden bazı yorumlar / geribildirim idealdir. Hepinize teşekkürler.

- (NSArray *)createArrayWithDictionaries:(NSString *)xmlDocument 
                               withXPath:(NSString *)XPathStr {

    NSError *theError = nil;
    NSMutableArray *mutableArray = [[[NSMutableArray alloc] init] autorelease];
    //NSMutableDictionary *mutableDict = [[NSMutableDictionary alloc] init];
    CXMLDocument *theXMLDocument = [[[CXMLDocument alloc] initWithXMLString:xmlDocument options:0 error:&theError] retain]; 
    NSArray *nodes = [theXMLDocument nodesForXPath:XPathStr error:&theError];
    int i, j, cnt = [nodes count];
    for(i=0; i < cnt; i++) {
        CXMLElement *xmlElement = [nodes objectAtIndex:i];
        if(nil != xmlElement) {
            NSArray *attributes = [NSArray array];
            attributes = [xmlElement attributes];
            int attrCnt = [attributes count];
            NSMutableDictionary *mutableDict = [[NSMutableDictionary alloc] init];
            for(j = 0; j < attrCnt; j++) {
                if([[[attributes objectAtIndex:j] name] isKindOfClass:[NSString class]]) 
                    [mutableDict setValue:[[attributes objectAtIndex:j] stringValue] forKey:[[attributes objectAtIndex:j] name]];
                else 
                    continue;
            }
            if(nil != mutableDict) {
                [mutableArray addObject:mutableDict];
            }
            [mutableDict release];  // This is causing bad things to happen.
        }
    }

    return (NSArray *)mutableArray;
}
Oluştur 26/02/2009 saat 23:32
kaynak kullanıcı
Diğer dillerde...                            


3 cevaplar

oy
5

İşte kod eşdeğer bir yeniden yazma var:

- (NSArray *)attributeDictionaries:(NSString *)xmlDocument withXPath:(NSString *)XPathStr {
    NSError *theError = nil;
    NSMutableArray *dictionaries = [NSMutableArray array];
    CXMLDocument *theXMLDocument = [[CXMLDocument alloc] initWithXMLString:xmlDocument options:0 error:&theError]; 
    NSArray *nodes = [theXMLDocument nodesForXPath:XPathStr error:&theError];

    for (CXMLElement *xmlElement in nodes) {
        NSArray *attributes = [xmlElement attributes];
        NSMutableDictionary *attributeDictionary = [NSMutableDictionary dictionary];
        for (CXMLNode *attribute in attributes) {
            [attributeDictionary setObject:[attribute stringValue] forKey:[attribute name]];
        }

        [dictionaries addObject:attributeDictionary];
    }

    [theXMLDocument release];
    return attributeDictionaries;
}

Ben sadece güveniyor başvuru yaptım edin theXMLDocument. Diziler ve sözlükler bu yöntemin kapsamı dışındadır canlı olmasıdır. arrayVe dictionarysınıf yöntemleri autoreleased örneklerini oluşturmak NSArrayve NSMutableDictionarynesneler. Arayan onları açıkça muhafaza etmezse, otomatik olarak uygulamanın olay döngüsünün sonraki go-round serbest olacak.

  • Ben de hiçbir zaman yürütülecek gidiyordu kodu kaldırıldı. CXMLNode nameYöntem bir dize döndürür söylüyor, bu test her zaman doğru olacaktır.
  • Eğer mutableDictbir nil, daha büyük sorunları var. O sessizce başarısız daha bir istisna atar böylesi daha iyi, bu yüzden de uzak o testi ile yaptı.
  • Ben de nispeten yeni kullanılan forKarşı değişkenleri ile deplasmanda yaptığı numaralandırma sözdizimi.
  • Ben biraz daha Kakao-imsi olmak için bazı değişkenleri ve yöntemi değiştirildi. Kakao genellikle özel olarak dönmek ne olursa olsun nesne serbest bırakılması için arayan sorumlu olmak için sürece "oluşturmak" gibi bir fiil kullanmak yanlış kabul edilir o çoğu dilde farklıdır.
  • Sen bir şey yapmadın theError. Bunu kontrol etmek ve hatayı bildirmek veya başka içerisinde geçer ya nilbunu kontrol etmeyecek eğer. Uygulamanın Kullanmak gitmiyorsun bir hata nesnesi oluşturmak yapımında hiçbir anlamı yoktur.

Bunun doğru yönde işaret almak yardımcı olur.

Cevap 27/02/2009 saat 00:18
kaynak kullanıcı

oy
1

Eh, üstündeki hat (mutableArray için mutableDict ekleme) çünkü gerçekten herhangi bir soruna neden olmamalıdır bırakmadan mutableDict otomatik olarak korur. Ben tam olarak koduyla yanlış neler olduğunu emin değilim iken ben öneririm birkaç genel şey var, (eğer "kötü şeyler" ne anlama geldiğini belirtmedi):

  1. hemen mutableArray sallanmasını vermeyin. düzenli bir alloc / init deyimi olalım ve bunu döndüğünüzde bunu otomatik salma ( "return [mutableArray sallanmasını];").

  2. theXMLDocument o dönmeden önce serbest bırakmak için emin olun sızıyor. Ayrıca, senin gibi saklayın gerekmez. alloc / init sadece sonsuza sızdırıyor sağlıyor tekrar koruyarak nesne 1'de sayımı korumak başlatarak işi yapar. korumak ve dönmeden önce bırakın ve sızıntı olmaz kurtulun.

  3. Sadece bir ipucu: başka bir yerde kullanırken bu yöntemin dönüş değeri korumak emin olun - Açıkça / muhafaza yere bırakın sürece ihtiyacınız olduğunda civarında olduğu garanti edilmez olarak sonuç autoreleased edilmiştir.

Aksi takdirde, bu kod gerekir çalışır. Hala Yoksa, ben denemek istiyorum başka bir şey belki yapıyor [mutableArray AddObject: [mutableDict] copy] serbest bırakıldığında mutableDict size hiçbir soruna neden olmasını sağlamak için.

Cevap 26/02/2009 saat 23:49
kaynak kullanıcı

oy
0

In Bellek Yönetimi Programlama Kılavuzu başlığı altında Yöntemleri Nesneleri döndürme (biraz aşağı kaydırma), doğru bellek yönetimi ile bir yöntemden nesneleri döndürmek için nasıl bir kaç basit örneği vardır.

Cevap 08/09/2010 saat 22:48
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more