c Obiettivo, perdita di memoria, la lettura da SQLite e l'assegnazione di valori a un NSDictionary e NSAarray

StackOverflow https://stackoverflow.com/questions/2034613

Domanda

Ho una lista di negozi in un file ListController. Fondai quindi un db SQLite, in cui ho memorizzato 60 negozi. In cima alla lista ho una barra di ricerca.

Ho fatto una classe chiamata DataController, che è responsabile per caricare e dati negozio db.

@interface DataController : NSObject {
 sqlite3 *database;
 NSArray *shops;    
 NSDictionary* dictionaryOfShops;
}

@property (nonatomic, retain) NSDictionary *dictionaryOfShops;
@property (nonatomic, retain) NSArray* shops;
-(void)initializeShops;

metodo initializeShops carica i dati dal db, e memorizza risultati nelle 2 puntelli in questo modo:

-(void)initializeShops{
    [dictionaryOfShops release];
    [shops release];

    NSMutableDictionary *dictionary = [[[NSMutableDictionary alloc] init] autorelease];

    if (sqlite3_open(....))
    NSString *query = ....
    if (sqlite3_prepare_v2(database, [query UTF8String],-1, &statement, nil) ==   SQLITE_OK) 
    {
        while (sqlite3_step(statement) == SQLITE_ROW) {

           int rId = sqlite3_column_int(statement, 0);
           char *rName = (char *)sqlite3_column_text(statement, 1);

           Shop* s  = [[Shop alloc] init];
           s.ID = rId;
           if(sName != nil) s.Name = [NSString stringWithUTF8String:rName];

               NSString *shopID = [[NSString alloc] initWithFormat:@"%d",s.ID];
           [dictionary setObject:s forKey:shopID];
           [shopID release];
           [s release];         
        }
        sqlite3_finalize(statement);
    }
    [query release];

    dictionaryOfShops = [[NSDictionary alloc] initWithDictionary:dictionary];
    shops =    [[NSArray alloc] initWithArray:[dictionary allValues]];

    dictionary = nil;
    [dictionary release];

       //Sorting
       NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"Name" ascending:YES];
    NSArray *sortedList =[self.shops sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]];
    self.shops = sortedList; 
    [sort release];
}

Il problema è che quando l'utente immette un testo nella ricerca bar, mi modificare il valore della query (aggiungendo COME ....) e poi chiamare di nuovo il metodo initializeShops. Questa seconda volta rende così tante perdite, (relativi alle proprietà della classe negozio) e perdite anche un NSDictionary e un NSArray.

Prima di scrivere questo a voi ho provato diverse soluzioni, ma almeno questo non perde nulla la prima volta che io chiamo initilizeShops.

Io accetto ogni suggerimento, visto che sono veramente bloccato su di esso.

PIU ':

La cosa veramente strana è la gestione della memoria di mio dizionario var e le 2 puntelli negozi e dictionaryOfShops. Con questo codice

NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
//add data to dictionary 
dictionaryOfShops = [[NSDictionary alloc] initWithDictionary:dictionary];
shops =    [[NSArray alloc] initWithArray:[dictionary allValues]];
[dictionary release]

Considerando che dictionaryOfShops e negozi sono due proprietà (nonatomic, mantenere) sintetizzato, come posso cambiare valore per loro, senza perdite?

La prima volta che mi passano attraverso questo metodo nulla viene trapelato, dalla seconda volta che si avvia a perdere così tanti oggetti (il contenuto delle collezioni).

È stato utile?

Soluzione 3

Ok, ho trovato l'errore. Nella mia classe negozio, mi rendo conto che non ha attuato il metodo

 -(void)dealloc

Così, quando ho comunicato vecchio dizionario (per prepararsi ad una nuova assegnazione), tutti i campi all'interno di esso non vengono rilasciati.

Altri suggerimenti

La prima domanda è Perché non basta usare Core Data? E 'molto probabile che sarà più veloce, richiede meno codice, e sarà molto più facile da mantenere nel tempo. Per essere franchi; SQLite è ingannevolmente difficile. Facile per iniziare, eccezionalmente difficile da ottenere.

In ogni caso, la gestione della memoria di dictionary è sbagliato. E 'solo di non si blocca perché scambiato l'ordine di assegnazione e il rilascio pari a zero come suggerito kennyTM. Vorrei suggerire non la creazione di un dizionario autoreleased.

In caso contrario, il codice come scritto sembra abbastanza Leakless a prima vista. Quindi:

  1. Si può fornire un po 'di codice? Qualcosa di interessante saggio di memoria accade altrove?

  2. Stai usando threading a tutti (o NSOperationQueue)?

  3. Hai passato sotto le perdite strumento e recuperò il backtrace di allocazione del oggetti specifici essere trapelato?

dictionary = nil;
[dictionary release];

Si prega di scambiare questi 2 affermazioni. In questa forma significa [nil release] che è un no-op.

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