iOS: приложение для сбоя нескольких запросов - PullRequest
3 голосов
/ 07 октября 2011

У меня есть приложение, в котором я обращаюсь к базе данных SQLite несколько раз ... Но, как только я получил доступ к базе данных один раз, все последующие попытки приводят к сбою приложения ... Я не уверен, что это потому, что база данных не была выпущена должным образом ...

Например, я запускаю поиск, чтобы заполнить табличное представление именами артистов. Выбрав художника, я перехожу к новому виду таблицы, где хочу заполнить его работами художника.

Но вот проблема. Я получаю доступ к базе данных, чтобы заполнить первое представление, но когда я хочу заполнить второе представление, оно не вводит sqlite3_prepare_v2 запроса ... так что это должно означать, что база данных все еще используется старым запросом ..

Итак, как правильно обрабатывать закрытие базы данных после использования?

В настоящее время я делаю запрос, как это:

-(NSArray *)findAllArtists
{
    NSMutableArray *returnArray = [[[NSMutableArray alloc] init] autorelease];

    NSString *query = @"SELECT * FROM Painting GROUP BY Artist";

    sqlite3_stmt *statement;

    if (sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, nil) 
    == SQLITE_OK) 
    {        
        while (sqlite3_step(statement) == SQLITE_ROW) 
        {
            char *uniqueIdChars = (char *) sqlite3_column_text(statement, 0);
            char *artistChars = (char *) sqlite3_column_text(statement, 1);
            NSString *uniqueId = [[NSString alloc] initWithUTF8String:uniqueIdChars];
            NSString *artist = [[NSString alloc] initWithUTF8String:artistChars];

            PaintingInfo *info = [[PaintingInfo alloc] initWithUniqueId:uniqueId artist:artist];
            [returnArray addObject:info];

            [uniqueId release];
            [artist release];
        }

        sqlite3_finalize(statement);
    }

    sqlite3_close(database);
    return returnArray;    
}

1 Ответ

4 голосов
/ 07 октября 2011

Вы должны взглянуть на упаковщик fmdb на github. Даже если вы не используете его, посмотрите на код.

Где вы открываете базу данных? Вы закрываете это в этом коде. Прежде чем вы позвоните снова, он должен быть открыт. Вам следует подумать о том, чтобы оставить его открытым на время однопользовательского приложения iOS и закрыть, когда вы закончите. Что произойдет, если вы просто удалите закрытый вызов?

Первое, что вы должны сделать, это проверить все ваши коды возврата для вызовов sqlite. например, с шагом вы не обрабатываете ничего, кроме SQLITE_ROW. По крайней мере, войдите другие. Также для завершения и закрытия вы не обрабатываете и не регистрируете других.

Кроме того, вы готовите (компилируете) оператор sql, но не сохраняете его. prepare_v2 возвращает вам скомпилированное утверждение. Сохраните его как переменную-член и вызовите сброс для него, прежде чем использовать его снова.

Чтобы ответить на ваш конкретный вопрос о том, как закрыть - вы должны учитывать, что некоторые утверждения, возможно, не были завершены. Вот мой метод close: (Кстати, ENDebug - это моя оболочка над NSLog)

- (void)close
{
    if (_sqlite3)
    {
        ENInfo(@"closing");
        [self clearStatementCache];

        int rc = sqlite3_close(_sqlite3);
        ENDebug(@"close rc=%d", rc);

        if (rc == SQLITE_BUSY) 
        { 
            ENError(@"SQLITE_BUSY: not all statements cleanly finalized");

            sqlite3_stmt *stmt; 
            while ((stmt = sqlite3_next_stmt(_sqlite3, 0x00)) != 0) 
            {
                ENDebug(@"finalizing stmt");
                sqlite3_finalize(stmt); 
            }

            rc = sqlite3_close(_sqlite3);
        }

        if (rc != SQLITE_OK)
        {
            ENError(@"close not OK.  rc=%d", rc);
        }

        _sqlite3 = NULL;
    }
}

наконец, рассмотрите возможность добавления гораздо большего количества журналов вместе с кодами возврата, чтобы вы могли получить больше информации.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...