2009-06-13 11 views
2

J'ai essayé de comprendre wh. sqy mon allocation d'objets continue rigth chaque fois que j'appelle cette fonction, Instruments rapporte pas de fuite, mais je reçois un diable de beaucoup d'objets en provenance deiphone sqlite3 la mémoire d'allocation d'objet en haut mais pas de fuite

sqlite3_exec --> sqlite3Prepare --> sqlite3Parser --> yy_reduce --> malloc & also a whole bunch from 

& from 

sqlite3Step --> sqlite3VdbeExec --> sqlite3BtreeInsert --> malloc 

J'ai essayé de le résoudre en suivant les suggestions affichées ici: http://www.iphonedevsdk.com/forum/iphone-sdk-development/7092-sqlite3-database-gobbling-up-memory.html mais n'ont pas été en mesure de le réparer

toute aide est appréciée, mon code est ci-dessous

+(void)getDesignationsInLibrary:(NSString *)library 
{ 
NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init];  
NSString *dbName = @"s8.sqlite"; 



NSArray *documentPaths = \ 
NSSearchPathForDirectoriesInDomains \ 
(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDir = \ 
[documentPaths objectAtIndex:0]; 
NSString *databasePath = \ 
[documentsDir stringByAppendingPathComponent:dbName]; 

[[DT sharedDT].designationsInLibrary removeAllObjects]; 

NSString *sqlString; 

for(int i=0;i<[[DT sharedDT].typesInLibrary count];i++) 
{ 

if(sqlite3_open([databasePath UTF8String], &db)==SQLITE_OK) 
{ 
    if (sqlite3_exec(db, "PRAGMA CACHE_SIZE=50;", NULL, NULL, NULL) != SQLITE_OK) { 
     NSAssert1(0, @"Error: failed to set cache size with message '%s'.", sqlite3_errmsg(db)); 
    } 
    NSMutableString *lib=[NSMutableString stringWithString:library]; 

    [lib appendString:@"-"]; 
    [lib appendString:[[DT sharedDT].typesInLibrary objectAtIndex:i]]; 

    if([DT sharedDT][email protected]"AISC Default") 
    { 
     sqlString = [NSString stringWithFormat:@"select DESIGNATION from \"%@\";",lib]; 
    } 
    else 
    { 
     sqlString = [NSString stringWithFormat:@"select DESIGNATION from \"%@\" order by cast(%@ as numeric) %@;",lib, [DT sharedDT].sortedBy, [DT sharedDT].sortAscDesc]; 
    } 

    const char *sql = [sqlString cStringUsingEncoding:NSASCIIStringEncoding]; 
    sqlite3_stmt *selectstmt; 

    if(sqlite3_prepare_v2(db,sql,-1,&selectstmt, NULL)==SQLITE_OK) 
    { 
      while(sqlite3_step(selectstmt)==SQLITE_ROW) 
      { 
       [[DT sharedDT].designationsInLibrary addObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt,0)]]; 
      } 
      sqlite3_finalize(selectstmt); 
     selectstmt=nil; 
    } 
} 

} 
sqlite3_close(db); 
[localPool release]; 
} 

Répondre

3

il semble que vous ouvrez db sur chaque cycle de la boucle, mais près une seule fois, avant la sortie de la fonction

donc essayez de changer:

 
    } 
sqlite3_close(db); 
[localPool release]; 
} 

à

 
     sqlite3_close(db); 
    } 

[localPool release]; 
} 

Ou mieux encore le changement:

 
for(int i=0;i [[DT sharedDT].typesInLibrary count];i++) 
{ 

if(sqlite3_open([databasePath UTF8String], &db)==SQLITE_OK) 
{ 
    if (sqlite3_exec(db, "PRAGMA CACHE_SIZE=50;", NULL, NULL, NULL) != SQLITE_OK) { 
     NSAssert1(0, @"Error: failed to set cache size with message '%s'.", sqlite3_errmsg(db)); 
    }

à:

 

if(sqlite3_open([databasePath UTF8String], &db)==SQLITE_OK) 
{ 
    if (sqlite3_exec(db, "PRAGMA CACHE_SIZE=50;", NULL, NULL, NULL) != SQLITE_OK) { 
     NSAssert1(0, @"Error: failed to set cache size with message '%s'.", sqlite3_errmsg(db));  
    } 

    for(int i=0;i [[DT sharedDT].typesInLibrary count];i++) 
    { 
    ... 

être parce que vous êtes toujours d'ouvrir la même base de données

+0

D'accord. Ouvrir la base de données sur chaque passage de boucle est une très mauvaise idée. –

0

essayez d'appeler sqlite3_exec avec:

pragma cache_size=1 

SQLite semble gober la mémoire pour la mise en cache.

+0

Je suis d'accord, vu ce comportement dans mon application aussi. sqlite prend beaucoup de mémoire pour la mise en cache. Fermer la base de données et l'ouvrir à nouveau dans didReceiveMemoryWarning semble fonctionner – lostInTransit