Objective-C: Festeminnehåndtering i en metode

stemmer
5

Jeg er nesten det å forstå enkle referansetelling / minnehåndtering i Objective-C, men jeg har en vanskelig tid med følgende kode. Jeg slipper mutableDict (kommentert i koden under) og det forårsaker skadelig atferd i min kode. Hvis jeg lar den minnelekkasje, det fungerer som forventet, men det er åpenbart ikke svaret her. ;-) Har noen av dere mer erfarne folk være så snill å peke meg i riktig retning hvor jeg kan omskrive noe av denne metoden for å bedre håndtere mitt minne fotavtrykk? Hovedsakelig med hvordan jeg administrere NSMutableDictionary * mutableDict, som det er den store synderen her. Jeg vil gjerne forstå problemet, og ikke bare kopiere / lime inn koden - så noen kommentarer / tilbakemeldinger er ideelt. Takk alle.

- (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;
}
Publisert på 26/02/2009 klokken 22:32
kilden bruker
På andre språk...                            


3 svar

stemmer
5

Her er en tilsvarende omskriving av koden:

- (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;
}

Merker jeg bare gjorde referansen telle på theXMLDocument. Det er fordi arrays og ordbøker leve utenfor rammen av denne metoden. Den arrayog dictionaryklassemetoder skape autoreleased forekomster av NSArrayog NSMutableDictionarygjenstander. Hvis den som ringer ikke uttrykkelig beholde dem, vil de automatisk bli utgitt på neste go-runde av programmet arrangement loop.

  • Jeg har også fjernet koden som aldri skulle bli henrettet. Den CXMLNode namemetoden sier det returnerer en streng, slik at testen vil alltid være sant.
  • Hvis mutableDicter nil, har du større problemer. Det er bedre at det kaster et unntak enn lydløst mislykkes, så jeg gikk bort med den testen, også.
  • Jeg brukte også den relativt nye foropptellingen syntaks, som gjør unna med benke variabler.
  • Jeg omdøpt noen variabler og metoden for å være litt mer kakao-ish. Kakao er forskjellig fra de fleste språk i at det er generelt ansett feil å bruke et verb som "skape" med mindre du spesielt ønsker å gjøre den som ringer ansvarlig for å slippe det objektet du kommer tilbake.
  • Du gjorde ikke noe med theError. Du bør heller sjekke det og rapportere feilen, ellers går i nilhvis du ikke kommer til å sjekke det. Det er ingen mening i å gjøre app bygge en feil objekt du ikke kommer til å bruke.

Jeg håper dette hjelper får du pekte i riktig retning.

Svarte 26/02/2009 kl. 23:18
kilden bruker

stemmer
1

Vel, vil slippe mutableDict egentlig ikke bør forårsake noen problemer fordi linjen over det (legge mutableDict til mutableArray) beholde den automatisk. Mens jeg er ikke sikker på hva som går galt med din kode (du ikke spesifisere hva "dårlige ting" betyr), er det noen generelle ting jeg vil foreslå:

  1. Ikke autoutgivelses mutableArray med en gang. La det være en vanlig Alloc / init erklæringen og autoutgivelses det når du kommer tilbake det ( "return [mutableArray autoutgivelses];").

  2. theXMLDocument lekker, sørg for å slippe at før retur. Dessuten trenger du ikke å beholde det som du er. Alloc / init gjør jobben ved å starte objektet beholde telling på 1, beholder det igjen bare sikrer den lekker alltid. Bli kvitt den beholde og slipp den før du går tilbake og det vil ikke lekke.

  3. Bare et tips: Pass på at du beholder returverdien av denne metoden når du bruker det andre steder - resultatet har blitt autoreleased som ikke er garantert å være rundt når du trenger det med mindre du eksplisitt beholde / slipper den et sted.

Ellers denne koden skal virke. Hvis det fortsatt ikke gjør det, er en annen ting jeg ville prøve kanskje gjør [mutableArray addObject: [mutableDict kopiere]] for å sikre at mutableDict fører deg ingen problemer når det slippes.

Svarte 26/02/2009 kl. 22:49
kilden bruker

stemmer
0

I minnehåndtering Programming Guide under temaet Retur objekter fra Methods (bla ned litt), er det noen enkle eksempler på hvordan du returnerer objekter fra en metode med riktig minnehåndtering.

Svarte 08/09/2010 kl. 21:48
kilden bruker

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