Domanda

Aggiorna : ho modificato il codice, ma il problema persiste ...

Ciao a tutti,
questo è il mio primo post qui - ho trovato questo posto una grande risorsa per risolvere molte delle mie domande. Normalmente faccio del mio meglio per risolvere qualsiasi cosa da solo, ma questa volta non ho davvero idea di cosa vada storto, quindi spero che qualcuno mi possa aiutare.
Sto costruendo un'app per iPhone che analizza un paio di file XML usando TouchXML. Ho un XMLParser di classe, che si occupa di scaricare e analizzare i risultati. Ricevo perdite di memoria quando analizzo più volte un file XML con la stessa istanza di XMLParser. Ecco uno degli snippet di analisi (solo la parte pertinente):

for(int counter = 0; counter < [item childCount]; counter++) {  
        CXMLNode *child = [item childAtIndex:counter];
        if([[child name] isEqualToString:@"PRODUCT"]) 
        {
            NSMutableDictionary *product = [[NSMutableDictionary alloc] init];
            for(int j = 0; j < [child childCount]; j++) {
                CXMLNode *grandchild = [child childAtIndex:j];
                if([[grandchild stringValue] length] > 1) {
                    NSString *trimmedString = [[grandchild stringValue] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
                    [product setObject:trimmedString forKey:[grandchild name]];
                }
            }

            // Add product to current category array
            switch (categoryId) {
                case 0:
                    [self.mobil addObject: product];
                    break;
                case 1:
                    [self.allgemein addObject: product];
                    break;
                case 2:
                    [self.besitzeIch addObject: product];
                    break;
                case 3:
                    [self.willIch addObject: product];
                    break;
                default:
                    break;
            }
            [product release];
        }

    }  

La prima volta, analizzo l'xml che non si verifica alcuna perdita negli strumenti, la prossima volta che lo faccio, ho ricevuto molte perdite (NSCFString / NSCFDictionary).
Instruments mi indica questa parte all'interno di CXMLNode.m , quando scavo in un oggetto trapelato:

theStringValue = [NSString stringWithUTF8String:(const char *)theXMLString];
if ( _node->type != CXMLTextKind )
   xmlFree(theXMLString);
}

return(theStringValue);  

Ho davvero passato molto tempo e ho provato diversi approcci per risolvere questo problema, ma finora senza successo, forse mi sto perdendo qualcosa di essenziale?

Qualsiasi aiuto è molto apprezzato, grazie!

È stato utile?

Soluzione

Il problema è probabilmente in questa riga:

[self.mobil addObject:[product copy]];

Richiedendo una copia del prodotto stai creando una nuova istanza NSMutableDictionary con un conteggio di mantenimento di 1. L'istanza mobil , tuttavia, aumenterà il mantenimento della copia conta quando gli invii il messaggio addObject: , quindi il conteggio di mantenimento della copia è ora 2. In generale, un oggetto è responsabile della gestione della propria memoria oggetto, quindi ogni volta che scrivi setFoo: o addObject: , puoi semplicemente passare l'oggetto direttamente, anche se è stato rilasciato automaticamente o stai pianificando di rilasciarlo subito dopo la chiamata; è responsabilità del destinatario conservare l'oggetto che stai passando se deve trattenerlo.

Poiché non hai assegnato la copia a nessuna variabile, non hai un puntatore che puoi utilizzare per diminuire il conteggio delle copie ora che non ti interessa più, quindi anche se mobil rilascia la copia del prodotto ad un certo punto, la copia non raggiungerà mai un conteggio di mantenimento di 0. L'istruzione [release del prodotto] alla fine del ciclo for rilascia il prodotto originale oggetto, non la copia che hai creato.

Invece, prova quanto segue e vedi se gli strumenti sono più felici:

[self.mobil addObject:product];

Altri suggerimenti

In termini semplici, ogni volta che usi copia , devi anche usare release / autorelease da qualche parte.

E in questo caso, la risposta ancora più semplice è di non utilizzare copy in primo luogo, poiché non stai facendo nulla con la versione originale di product dopo l'hai copiato.

Ho risolto il problema da solo. È stato un po 'stupido, ma forse qualcuno potrebbe imbattersi nella stessa cosa, quindi pubblicherò qui.

1) Ho configurato un array mutabile come variabile di istanza come questa:

@interface XMLParser : NSObject {

// ...  
NSMutableArray *mobil;  
// ...  
}   
@property(nonatomic, retain) NSMutableArray *mobil;  
@end  

Ogni volta che volevo ripristinare nuovi dati all'interno facevo:
    self.mobil = zero;
Il che non ha fatto quello che volevo fare, quindi questo è l'approccio migliore:
    [self.mobil removeAllObjects];

2) Il metodo dealloc deve essere così per correggere le perdite (perché mobil è definito come una proprietà):
    - (vuoto) dealloc {
      [mobil release];
      self.mobil = zero;
  }

Accidenti, è stato un sacco di lavoro da scoprire - spero che salvi qualcun altro un po 'di tempo :-)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top