当我尝试在循环中向字符添加字典时获取重复值

时间:2016-09-09 16:08:10

标签: objective-c

这是我的测试应用程序的代码,我希望在下一个视图控制器上显示用户,但是当我运行并尝试检索值时,它会给我重复的值。我使用了NSMutableDictionaryNSMutableArray

#import "DBManager.h"

static DBManager *sharedInstance = nil;
static sqlite3 *database = nil;
static sqlite3_stmt *statement = nil;

@implementation DBManager

-(void) getsaveData:(NSString *)Username
{
    const char *dbpath = [newFileAtPath UTF8String];
    NSMutableArray *userArray = [[NSMutableArray alloc]init];
    if (sqlite3_open(dbpath, &database)==SQLITE_OK) {
        NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
        NSString *getSQL = [NSString stringWithFormat:@"SELECT * FROM USERS WHERE USERNAME != \"%@\"",Username];
        const char *retrievestmt = [getSQL UTF8String];
        if(sqlite3_prepare_v2(database, retrievestmt, -1, &statement, NULL)==SQLITE_OK)
        {
            while(sqlite3_step(statement)==SQLITE_ROW)//in this while loop i am getting repeated values
            {
               NSString *User_ID = [[NSString alloc] initWithUTF8String: (const char *) sqlite3_column_text(statement, 0)];
                [userInfo setObject:User_ID forKey:@"ID"];
                //[userArray addObject:User_ID];

                NSString *User_Email = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)];
                [userInfo setObject:User_Email forKey:@"Email"];
                //[userArray addObject:User_Email];

                NSString *Password = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 2)];
                [userInfo setObject:Password forKey:@"Email"];
                //[userArray addObject:Password];

                NSString *User_name = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 3)];
                [userInfo setObject:User_name forKey:@"Username"];
                //[userArray addObject:User_name];

                NSString *User_Avatar = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 4)];
                [userInfo setObject:User_Avatar forKey:@"Avatar"];
                //[userArray addObject:User_Avatar];

                [userArray addObject:userInfo];
                NSLog(@"userArray %@",userArray);

            }
            sqlite3_reset(statement);
        }
    }
}

@end

while循环中,我正在纠错。

我尝试了多次使用多种解决方案,请帮我解决这个问题。

1 个答案:

答案 0 :(得分:2)

问题很简单 - 您错误地重复使用userInfo字典。您需要在每次循环迭代中创建一个新实例。

移动线:

NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];

紧跟在while循环线之后。

您的代码还有许多其他问题:

  1. 您永远不会关闭数据库。
  2. 你永远不会完成准备好的陈述。
  3. 您不必重置预先准备好的陈述。
  4. 您没有足够的错误检查/记录。
  5. 您没有使用标准命名约定。
  6. 您没有使用标准的whitespacing,这使您的代码更难阅读。
  7. 您不使用一致的花括号放置。选择一种风格并随处使用。
  8. 当你不应该使用静态变量时。
  9. 永远不要使用stringWithFormat:构建SQL语句。正确地将值绑定到查询。
  10. 切勿在查询中使用SELECT *。明确列出列以确保获得一致和预期的列值。
  11. 以下是针对这些问题更新的代码:

    #import "DBManager.h"
    
    static DBManager *sharedInstance = nil;
    
    @implementation DBManager
    
    - (void)getsaveData:(NSString *)username {
        const char *dbpath = [newFileAtPath UTF8String];
        NSMutableArray *userArray = [[NSMutableArray alloc] init];
        sqlite3 *database;
        if (sqlite3_open(dbpath, &database) == SQLITE_OK) {
            const char *retrievestmt = "SELECT USER_ID, USER_EMAIL, PASSWORD, USER_NAME, USER_AVATAR FROM USERS WHERE USERNAME != ?"; // replace * with actual column names
            sqlite3_stmt *statement;
            if (sqlite3_prepare_v2(database, retrievestmt, -1, &statement, NULL) == SQLITE_OK) {
                sqlite3_bind_text(statement, 1, [username UTF8String], -1, SQLITE_TRANSIENT);
                while (sqlite3_step(statement) == SQLITE_ROW) {
                    NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
                    NSString *userID = [[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 0)];
                    userInfo[@"ID"] = userID;
    
                    NSString *userEmail = [[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 1)];
                    userInfo[@"Email"] = userEmail;
    
                    NSString *password = [[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 2)];
                    userInfo[@"Password"] = password;
    
                    NSString *username = [[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 3)];
                    userInfo[@"Username"] = username;
    
                    NSString *userAvatar = [[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 4)];
                    userInfo[@"Avatar"] = userAvatar;
    
                    [userArray addObject:userInfo];
                }
    
                sqlite3_finalize(statement);
    
                NSLog(@"userArray %@",userArray);
            } else {
                NSLog(@"Unable to prepare the statement at %s: %s", retrievestmt, sqlite3_errmsg(database));
            }
    
            sqlite3_close(database);
        } else {
            NSLog(@"Unable to open the database at %@: %s", dbpath, sqlite3_errmsg(database));
        }
    }
    
    @end