/ / Uzyskiwanie powtarzających się wartości, gdy próbuję dodać słownik do tablicy w pętli - objective-c

Uzyskiwanie powtarzających się wartości, gdy próbuję dodać słownik do tablicy w pętli - obiekt-c

To jest mój kod dla mojej aplikacji testowej, w której chcę pokazać użytkownikom następny kontroler widoku, ale kiedy uruchamiam i próbuję pobrać wartości, podaje mi powtarzające się wartości. używałem NSMutableDictionary i NSMutableArray.

#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

w while Pętla Kieruję na błąd.

Próbowałem wiele razy z wieloma rozwiązaniami, pomóż mi to naprawić.

Odpowiedzi:

2 dla odpowiedzi № 1

Problem jest prosty - niepoprawnie używasz ponownie pliku userInfo słownik. Musisz utworzyć nową instancję w każdej iteracji pętli.

Przenieś linię:

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

zaraz po while linia pętli.

Masz również wiele innych problemów z kodem:

  1. Nigdy nie zamykasz bazy danych.
  2. Nigdy nie finalizujesz przygotowanego oświadczenia.
  3. Niepotrzebnie resetujesz przygotowane oświadczenie.
  4. Masz niewystarczające sprawdzanie / rejestrowanie błędów.
  5. Nie używasz standardowych konwencji nazewnictwa.
  6. Nie używasz standardowych odstępów, co sprawia, że ​​kod jest trudniejszy do odczytania.
  7. Nie używasz spójnego rozmieszczenia nawiasów klamrowych. Wybierz styl i używaj go wszędzie.
  8. Używasz zmiennych statycznych, kiedy nie powinno.
  9. Nigdy nie buduj instrukcji SQL przy użyciu stringWithFormat:. Prawidłowo powiąż wartości z zapytaniem.
  10. Nigdy nie używaj SELECT * w zapytaniu. Wyraźnie wymień kolumny, aby zapewnić spójne i oczekiwane wartości kolumn.

Oto Twój kod zaktualizowany pod kątem następujących problemów:

#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