【问题标题】:Create NSMutableDictionary with NSString使用 NSString 创建 NSMutableDictionary
【发布时间】:2014-10-25 09:48:02
【问题描述】:

我想用NSString 创建一个NSMutableDictionnary

-(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;

}

我认为这是最简单的方法,只有 2 行,但它仍然拒绝它:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString count]: unrecognized selector sent to instance 0x1093180c0'

【问题讨论】:

  • 添加一个异常断点,Xcode会告诉你这个异常是在哪里产生的......
  • 我知道这是一个循环问题,但我可以弄清楚如何以简单的方式构建字典 ..
  • 您已经解决了循环问题。你现在得到一个完全不同的错误。您可以在这里找到解决方案:stackoverflow.com/questions/18888059/…
  • 错误现在改变了..

标签: ios objective-c nsstring nsmutabledictionary


【解决方案1】:

所以我终于设法解决了这个问题!简单的解决方案,有点慢,但现在仍然有效! 我的问题与我一开始的想法完全不同。 我尝试用 NSString 制作一个字典,并且在每个循环中都替换了值。所以当我一开始有 84 个产品时,我只得到了 20 个产品,建立了字典,但它崩溃了,因为我用 NSArray 制作了一个 DIctionnary!我没有注意到,所以我终于找到了解决方案(我将用for替换while):

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++;
        }

谢谢大家的帮助:)

【讨论】:

    【解决方案2】:

    我认为崩溃的原因是这些行

     tab = (char*)sqlite3_column_text(compiledStatement, [[dictionary objectForKey:@"name_fr"] intValue]);
     NSString *final = [NSString stringWithUTF8String:tab];
    

    如果char值为nil,转成字符串值可能会出现异常,即表中对应行基本没有值的情况。

    那就试试吧

    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
    }
    

    【讨论】:

    • 已经检查过 (final != nil),它是一样的。我的问题和我想的完全不同……
    • stringWithUTF8String 可能是罪魁祸首
    【解决方案3】:

    为什么不直接从数据库中获取数据时创建字典

    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];
                }
            }
    

    【讨论】:

    • 我正在尝试这样做:pastebin.com/DkVQdrXa 但它告诉我:[__NSCFString count]: unrecognized selector sent to instance 0x10973e5c0 2014-09-01 10:51:37.711 SQLite-TUO[22126 :60b] *** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[__NSCFString 计数]:无法识别的选择器发送到实例 0x10973e5c0”
    • 您不需要使用任何索引,您可以直接在字典中传递字符串值。
    • 还要检查字符串的长度。
    • 仍然错误:*** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[__NSCFString 计数]:无法识别的选择器已发送到实例 0x109532470”
    • 好的我认为它有效,但我的字典每个键只包含一个值,它替换以前的值,例如:第一次:G =“Great”,第二次:G =“Good”,,但我想要 G = "Great", "Good" (错误仍然存​​在,但它来自视图控制器
    【解决方案4】:

    while (array[j]) 更改为while (j &lt; [array count])

    【讨论】:

    • 我这样做了,并且用for更改了while,但仍然是同样的错误,并且日志很好..
    • 也许,字符串 NSString *firstLetter = [array[i] substringToIndex:1]; 有问题?改为 if(i
    • 我不认为它工作正常,当我想在日志中打印 firstLetter 和 secondLetter 时,它们打印得很好,并且 if 很好..
    • 您的索引有问题
    【解决方案5】:

    您看到的是您的array 变量在其边界之外被访问。索引66 之后根本没有元素,因为它只包含 67 个元素。

    您在迭代 array 时使用了难以阅读的循环结构。在您的情况下,您可以将循环转换为使用 for 构造,而不是 while

    for (int j = 0; j < [array count]; j++) {
    ...
        for (int i = 0; i < [array count]; i++) {
        ...
        }
    }
    

    这样做不再需要将i 重置为0,也不需要在循环头之外增加ij(删除底部的i++j++ 语句你的循环)。

    【讨论】:

    • 请将您使用for 构造实现的两个嵌套循环发布到pastebin.com,然后在此处提供链接作为评论。
    • 我用 for 循环修改了我的第一篇文章
    • 你混淆了变量名。第二个循环可能应该说for (int i = ...。从代码开头删除int i 的声明,它现在没用了。
    • 是的,对不起,我遵循您发布的确切代码.. 我的错!所以它仍然不起作用,现在不是同样的错误:Cannot find executable for CFBundle .... 也许有一个最简单的方法来构建 NSDictionnary ?
    • 我更正了我的代码 sn-p。更新您的问题以反映您的确切问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多