I am pretty new to Objective C, and even brand new to using SQL inside my apps. I am trying to get a running count of the state of items in my database. If you can imagine a todo type app, with a number of items in each category. The method below first retrieves the total number of items in the category, then loops through each category and determines which ones have the value of “Yes” (as in yes it is checked/completed). The code works, but I have this tied to a UIButton, so when the button is pressed the method below gets called as well as the UIPopover that displays the data. When the UIButton is pressed the first few times, it is very responsive and immediately opens the UIPopover, however when it is pressed many times, is slows down, eventually it takes a second or two to open. I want to know the best way to do this correctly, without hogging memory and keeping everything responsive. I must be doing something completely wrong as it gets more and more sluggish as you press the button to open the popover. Any ideas or suggestions would be really appreciated.
-(void)doCount{
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *dbPath = [documentsDir stringByAppendingPathComponent:@"ListDatabase.sql"];
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
for (NSString *element in self.countArray){
NSString *retrieveValue = [prefs objectForKey:@"selectedList"];
const char *sql = [[NSString stringWithFormat:@"SELECT COUNT(itemCategory)FROM '%@' WHERE itemCategory='%@'",retrieveValue,element]UTF8String];
sqlite3_stmt *selectstmt;
if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) {
while(sqlite3_step(selectstmt) == SQLITE_ROW) {
int totalcount = sqlite3_column_int(selectstmt,0);
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setInteger:totalcount forKey:@"count"];
}
const char *sql = [[NSString stringWithFormat:@"SELECT COUNT(itemDone)FROM '%@' WHERE itemDone='Yes' AND itemCategory ='%@'",retrieveValue,element]UTF8String];
sqlite3_stmt *getcountstmt;
if(sqlite3_prepare_v2(database, sql, -1, &getcountstmt, NULL) == SQLITE_OK) {
while(sqlite3_step(getcountstmt) == SQLITE_ROW) {
int count = sqlite3_column_int(getcountstmt,0);
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
int totalcount = [prefs integerForKey:@"count"];
NSString *catCount = [NSString stringWithFormat: @"%i/%i",count,totalcount];
[prefs setObject:catCount forKey:element];
}
}
sqlite3_finalize(selectstmt);
sqlite3_finalize(getcountstmt);
}
}
}
sqlite3_close(database);
//[self getFinishedItems];
}
Greg,
here are few improvements in the above code…
also, you can put your dbPath creation code somewhere else or say set it up globally so that it won’t create the autoreleased object which also occupy the memory…