Возникли проблемы с доступом к моим объектам NSArray, которые загружаются с данными sqlite

Я думаю, что есть некоторые основные недоразумения, как это должно работать, и я был бы признателен за любую помощь. Я пытался написать некоторые функции, которые будут извлекать данные из таблицы sqlite, помещать их в объект и сохранять этот объект в массив. Затем к этому массиву будут обращаться другие подпрограммы. В этом классе есть еще много чего, и я не хочу засорять форум. Проблемы, с которыми я имею это:

1) Я могу только получить доступ к окончательным значениям, которые были помещены в массив. Я неправильно сохраняю объект "Пользователь" в массив?

2) Предполагая, что я правильно получаю объекты в массиве, правильно ли я их вытаскиваю? Я добавил образец рутины внизу.

3) Может ли кто-нибудь с большим опытом упомянуть более эффективный способ сделать это? Я все еще пытаюсь получить свои навыки программирования xcode под себя и буду признателен за любые предложения по написанию более чистого кода.

// ** заголовок SQLiteFunctions

#import <sqlite3.h>
#import "Users.h"

@interface SQLiteFunctions : NSObject
{
@public
    // initializing public variables
    NSMutableArray *returnData;

@private
    // initializing private variables
    sqlite3 *dbPointer;
    sqlite3_stmt *sqlStatement;
    NSArray *paths;
    NSString *documentsDirectory;
    NSString *databasePath;
    char *error;
    Users *users;
}

// initializing public member functions
-(BOOL)openDatabase: (NSString *) table_name;
-(BOOL)openBundleDatabase;
-(BOOL)openNonBundleDatabase;
-(void)closeDatabase;
-(BOOL)getRecords:(const char *)sqlquery;
-(int)getUserRecords:(const char *)sqlquery;

@end

// ** Реализация SQLiteFunctions

-(int)getUserRecords:(const char *)sqlquery
{
    // retreiving database values
    users = [[Users alloc] init];

    // initializing return data array
    returnData = [[NSMutableArray alloc] init];

    // testing prepare statement for verse sql
    if(sqlite3_prepare(dbPointer, sqlquery, -1, &sqlStatement, NULL) == SQLITE_OK)
    {
        // looping through existing return rows
        while (sqlite3_step(sqlStatement)==SQLITE_ROW)
        {
            // retreiving database values
            users->user_id = sqlite3_column_int(sqlStatement,0);
            users->user_name = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 1)];

            // adding verse object to the return data array
            [returnData addObject:users];
        }
    }
    else
    {
        // logging problem with prepare
        NSLog(@"Problem with prepare statement:  %s", sqlite3_errmsg(dbPointer));
        return NO;
    }

    // returning number of rows in the array
    return [returnData count];
}

// ** Пример использования

// retreiving the number of users from the database
SQLiteFunctions *sql = [[SQLiteFunctions alloc] init];
Functions *func = [[Functions alloc] init];

// testing for successful open
if([sql openDatabase:@"users"])
{
    // testing for that profile name existing already
    if([sql getUserRecords:[func strCat:@"SELECT * FROM  users;":nil:nil:nil:nil]] > 0)
    {
        int user_id;
        NSString *user_name;
        for(Users *myUser in sql->returnData)
        {
            user_id = myUser.user_id;
            user_name = myUser.user_name;
            // do other stuff with values
        }
    }
}

1 ответ

Решение

Проблема с добавлением объектов в ваш массив
Проблема с вашим массивом состоит в том, что вы продолжаете обновлять значения одного и того же экземпляра объекта User и добавлять его в массив снова и снова.

Чтобы это исправить, переместите users = [[Users alloc] init]; линия внутри вашего для цикла.

Доступ к объектам в вашем массиве
Доступ к объектам в массиве - это хорошо, если вам нужно пройти через все (или хотя бы многие) объекты. Если вам нужен только конкретный объект, вы можете использовать:

Users *user5 = [sql->returnData objectAtIndex:5];

Более серьезная проблема, однако, заключается в том, что вы действительно не должны получать доступ к ивару вне вашего собственного класса. Вместо публичного ивара (returnData), вы должны создать объявленное свойство:

Сначала удалите строку объявления ivar (NSMutableArray *returnData;), а затем добавьте это после блока, который содержит все ваши ивары (чуть выше вашего // initializing public member functions комментарий):

@property (неатомный, сильный) NSMutableArray *returnData;

Затем вы получите доступ к нему с помощью метода доступа: sql.returnData или же [sql returnData] вместо sql->returnData,

Другие вопросы по тегам