Reputation: 1509
I want to create a NSMutableDictionnary
with a NSString
.
-(NSMutableDictionary *)getList{
//Declaration d'un objet SQLITE
sqlite3 *database;
//Declaration de notre String qui sera retourne
NSMutableDictionary *aromaArray = [[NSMutableDictionary alloc] init];
// Ouverture de la base de donnees
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
//Chaine de caracteres de la requete
const char *sqlStatement = "SELECT name_fr FROM aroma_huiles";
//Creation de l'objet statement
sqlite3_stmt *compiledStatement;
//Compilation de la requete et verification du succes
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// Creation d'un dictionnaire des noms de colonnes
NSDictionary *dictionary = [self indexByColumnName:compiledStatement];
//char **final = malloc(4096 * sizeof(*final));
NSMutableArray *array = [[NSMutableArray alloc] init];
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
//Assigne la valeur dans la chaine de caracteres
char *tab;
tab = (char*)sqlite3_column_text(compiledStatement, [[dictionary objectForKey:@"name_fr"] intValue]);
NSString *final = [NSString stringWithUTF8String:tab];
if (final != nil) {
NSString *firstLetter = [final substringToIndex:1];
[aromaArray setObject:final forKey:firstLetter];
}
}
}
else {
//Envois une exception en cas de probleme de requete
NSAssert1(0, @"Erreur :. '%s'", sqlite3_errmsg(database));
}
// Finalisation de la requete pour liberer la memoire
sqlite3_finalize(compiledStatement);
}
else {
//Envois une exception en cas de probleme d'ouverture
NSAssert(0, @"Erreur d'ouverture de la base de donnees");
}
//Fermer la base de donnees
sqlite3_close(database);
//Retourne la valeur
return aromaArray;
}
I think this is the easiest method, only 2 lines, but It still reject it :
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString count]: unrecognized selector sent to instance 0x1093180c0'
Upvotes: 0
Views: 135
Reputation: 1509
So I finally manage to fix the problem ! Simple solution, a bit slow but still it works now ! My problem was totally different than what I thought at the begining. I tried to make a Dictionnary with NSString, and the values were replaced at each loop .. So I only got 20 products when I had 84 at the begining, the Dictionnary was built, but It crashed because I nedded a DIctionnary made with NSArray ! I didn't notice that, so I finally find the solution (I will replace the while with for) :
tab = (char*)sqlite3_column_text(compiledStatement, [[dictionary objectForKey:@"name_fr"] intValue]);
NSString *final = [NSString stringWithUTF8String:tab];
if (final != nil && final.length >0) {
[array addObject:final];
}
}
int i = 0;
int j = 0;
NSMutableArray *table = [[NSMutableArray alloc] init];
while (i < [array count])
{
NSString *firstLetter = [array[i] substringToIndex:1];
table = [[NSMutableArray alloc] init];
while (j < [array count])
{
NSString *secondLetter = [array[j] substringToIndex:1];
if ([secondLetter isEqualToString:firstLetter]) {
[table addObject:array[j]];
}
j++;
}
j = 0;
[aromaArray setObject:table forKey:firstLetter];
i++;
}
Thank you all for your help :)
Upvotes: 0
Reputation: 20021
I think the reason for the crash is these lines
tab = (char*)sqlite3_column_text(compiledStatement, [[dictionary objectForKey:@"name_fr"] intValue]);
NSString *final = [NSString stringWithUTF8String:tab];
if the char value is nil and is converted to the string value an exception may come.ie the case appear when basically there is no value in the corresponding row in table.
so try
tab = (char*)sqlite3_column_text(compiledStatement, [[dictionary objectForKey:@"name_fr"] intValue]);
if(tab){
NSString *final = [NSString stringWithUTF8String:tab];
//everything else that comes under is to be here
}
Upvotes: 0
Reputation: 2139
Why don't you directly create dictionary while you fetch data from DB
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
//Assigne la valeur dans la chaine de caracteres
char *tab;
tab = (char*)sqlite3_column_text(compiledStatement, [[dictionary objectForKey:@"name_fr"] intValue]);
NSString *final = [NSString stringWithUTF8String:tab];
if (final != nil && final.length >0) {
//get substring from string here
NSString *firstLetter = [final substringToIndex:1];
//Add objects in dictionary here
[aromaArray setObject:final forKey:firstLetter];
}
}
Upvotes: 0
Reputation: 21461
What you see is that your array
variable is accessed outside of its bounds. There is simply no element after index 66
as it contains only 67 elements.
You are using a hard to read loop constructs when iterating over array
. Instead of while
in your case you can transform your loops to use the for
construct:
for (int j = 0; j < [array count]; j++) {
...
for (int i = 0; i < [array count]; i++) {
...
}
}
Doing so there's no need anymore for resetting i
to 0
and there's no need for increasing i
and j
outside of the loop header (remove i++
and j++
statements at the bottom of your loops).
Upvotes: 1