YosiFZ
YosiFZ

Reputation: 7900

Sqlite crash app

i am using this code to insert names to table,i have a problem that after 150 +/- names the app crash with this log:

 Received memory warning. Level=1
 Received memory warning. Level=2

this is the code,did i done something wrong?

if (sqlite3_open([dataPath UTF8String], &database) == SQLITE_OK) {
    for (int i = 0 ; i < count; i++) {          
        sqlite3_stmt *insertStmt = nil;
        NSString *name = [song valueForProperty:MPMediaItemPropertyTitle];

        if(insertStmt == nil) 
        {
            NSString *statement = [NSString stringWithFormat:@"INSERT INTO Songs (name) VALUES (?)"];
            const char *insertSql = [statement UTF8String];

            if(sqlite3_prepare_v2(database, insertSql, -1, &insertStmt, NULL) != SQLITE_OK){
                NSLog(@"Error while creating insert statement.");
                insertStmt = nil;
                continue;
            }

            sqlite3_bind_text(insertStmt, 1, [name UTF8String], -1, SQLITE_TRANSIENT);


            if(SQLITE_DONE != sqlite3_step(insertStmt)){
                NSLog(@"Error while inserting data.");
                insertStmt = nil;
                continue;
            }
            else{}

            sqlite3_reset(insertStmt);
            insertStmt = nil;
        }

        [delegate IPodLibraryFinishEntity:self];
    }

    sqlite3_close(database);

}

Upvotes: 1

Views: 1548

Answers (3)

Tomasz Wojtkowiak
Tomasz Wojtkowiak

Reputation: 4920

Your code is not optimal. You should place all prepare methods before the loop.

if (sqlite3_open([dataPath UTF8String], &database) == SQLITE_OK) {

    sqlite3_stmt *insertStmt = nil;
    NSString *name = [song valueForProperty:MPMediaItemPropertyTitle];

    if(insertStmt == nil) {
        NSString *statement = [NSString stringWithFormat:@"INSERT INTO Songs (name) VALUES (?)"];
        const char *insertSql = [statement UTF8String];

        if(sqlite3_prepare_v2(database, insertSql, -1, &insertStmt, NULL) != SQLITE_OK){
            NSLog(@"Error while creating insert statement.");
            insertStmt = nil;
            return;
        }
    }
    for (int i = 0 ; i < count; i++) {          
        sqlite3_bind_text(insertStmt, 1, [name UTF8String], -1, SQLITE_TRANSIENT);

        if(SQLITE_DONE != sqlite3_step(insertStmt)){
            NSLog(@"Error while inserting data.");
            continue;
        }
        else{}

        sqlite3_clear_bindings(insertStmt); //release bindings
        sqlite3_reset(insertStmt);

        [delegate IPodLibraryFinishEntity:self];
    }
    sqlite3_close(database);
}

Upvotes: 0

alloc_iNit
alloc_iNit

Reputation: 5183

Before starting each Insert statement use sqlite3_open and after execution of query put sqlite3_close statement. So that it wont make database object busy anymore after each Insert query execution.

Upvotes: 1

zaph
zaph

Reputation: 112857

Use instruments to check for memory loss due to retained but not leaked memory. The latter is unused memory that is still pointed to. Use Heapshot in the Allocations instrument on Instruments.

For HowTo use Heapshot to find memory creap, see: bbum blog

Basically there method is to run Instruments allocate tool, take a heapshot, run an intuition of your code and another heapshot repeating 3 or 4 times. This will indicate memory that is allocated and not released during the iterations.

To figure out the results disclose to see the individual allocations.

If you need to see where retains, releases and autoreleases occur for an object use instruments:

Run in instruments, in Allocations set "Record reference counts" on on (you have to stop recording to set the option). Cause the picker to run, stop recording, search for there ivar (datePickerView), drill down and you will be able to see where all retains, releases and autoreleases occurred.

Upvotes: 1

Related Questions