Как привязать текстовое значение к базе данных sqlite3 в iphone - PullRequest
0 голосов
/ 27 ноября 2009

Я занимаюсь разработкой приложения для фильма, в котором мне нужно получить данные из базы данных с учетом некоторых ограничений. Он отлично работает в первом случае, но когда я пытаюсь получить данные во второй раз, возникает исключение времени выполнения (приложение вылетает). Мне нужно связать 3 заполнителя. 2 - текст, 1 - целочисленный тип. Вот код, который я использую для извлечения данных из базы данных.

-(void) Data2
{
 databaseName = @"Cinema1.sqlite";

 NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
 NSString *documentsDir = [documentPaths objectAtIndex:0];
 databasePath =[documentsDir stringByAppendingPathComponent:databaseName];

 [self checkAndCreateDatabase];


 sqlite3 *database;
 if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK)
 {
  if(detailStmt == nil)
  {
   const char *sql = "Select PVR,Fame,Cinemax,Big from listing where UPPER(State) = UPPER(?) and UPPER(City) = UPPER(?) and ZIP = ?";   
   if(sqlite3_prepare_v2(database, sql, -1, &detailStmt, NULL) == SQLITE_OK) 
   {  
    NSLog(@"Hiiiiiii");
    sqlite3_bind_text(detailStmt, 1, [t1 UTF8String], -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(detailStmt, 2, [t2 UTF8String], -2, SQLITE_TRANSIENT);
    sqlite3_bind_int(detailStmt, 3, t3);
    if(SQLITE_DONE != sqlite3_step(detailStmt))
    {
     NSLog(@"Helllloooooo");
     NSString *pvr= [NSString stringWithUTF8String:(char *)sqlite3_column_text(detailStmt, 0)];
     NSString *fame= [NSString stringWithUTF8String:(char *)sqlite3_column_text(detailStmt, 1)];;
     NSString *cinemax = [NSString stringWithUTF8String:(char *)sqlite3_column_text(detailStmt, 2)];
     NSString *big= [NSString stringWithUTF8String:(char *)sqlite3_column_text(detailStmt, 3)];
     pvr1 = pvr;
     fame1 = fame;
     cinemax1 = cinemax;
     big1 = big;
     NSLog(@"PVR %@ Fame %@ Cinemax %@ Big %@",pvr1,fame1,cinemax1,big1);
    }
   }
   sqlite3_finalize(detailStmt);
  }
 }
 sqlite3_close(database);}

Может ли кто-нибудь помочь мне с этим.

Ответы [ 3 ]

3 голосов
/ 27 ноября 2009

Вы используете sqlite3_prepare_v2() и sqlite3_finalize() неправильно. Вы готовите утверждение только один раз, а затем можете привязать к нему значения столько, сколько захотите. Когда вы закончите, вы звоните sqlite3_reset(). Когда вы полностью закончили с этим утверждением и больше никогда не будете его использовать (т.е. вы выходите из приложения), тогда вы используете finalize.

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

Смотрите также здесь: http://www.sqlite.org/c3ref/prepare.html

2 голосов
/ 27 ноября 2009

Как указывает Тоби, переменные pvr, fame, cinemax и big (и переназначенные pvr1, fame1, cinemax1 и big1) автоматически освобождаются при возврате из -stringWithUTF8String :, но вы никогда не сохраняете их. Любой доступ к этим переменным после этой точки вызовет сбой.

Вы говорите, что видите выброшенное исключение. Может быть полезно узнать, что это за исключение, изучив вывод консоли. Кроме того, вы можете включить точку останова на objc_exception_throw в libobjc.A.dylib, а затем отладить с включенными точками останова, чтобы найти точную строку, на которой возникает это исключение.

1 голос
/ 27 ноября 2009

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

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