2011-10-07 2 views
3

SQLite 데이터베이스에 여러 번 액세스하는 응용 프로그램이 있습니다 .. 그러나 한 번 데이터베이스에 액세스하면 모든 후속 시도가 응용 프로그램을 중단시킵니다 ... I 'm 데이터베이스가 제대로 릴리스되지 않았기 때문에 확실하지 않은 경우 ...iOS : 여러 쿼리가 응용 프로그램을 충돌

예를 들어, 검색을 실행하여 테이블 뷰에 아티스트 이름을 채 웁니다. 일단 아티스트를 선택하면 새로운 테이블 뷰로 이동하여 아티스트의 작품으로 채울 수 있습니다.

하지만 여기에 문제가 있습니다. 데이터베이스에 액세스하여 첫 번째보기를 채우지 만 두 번째보기를 채우려는 경우 쿼리의 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;  
} 
+0

'findAllArtists' 메소드에서 닫는 데이터베이스 만 볼 수 있습니다 만, 포인터를 생성하는 곳은 어디입니까? '-findAllArtists'에서'sqlite3_close (database);를 제거하면 도움이 될까요? –

답변

4

당신은 GitHub의에서 fmdb 래퍼 봐야한다. 사용하지 않더라도 코드를 살펴보십시오.

어디에서 데이터베이스를여십니까? 이 코드에서 끝내고 있습니다. 다시 전화하기 전에 열려 있어야합니다. 단일 사용자 iOS 앱을 실행하는 동안 계속 열어두고 작업이 끝나면 종료하는 것을 고려해야합니다. 가까운 전화를 단순히 제거하면 어떻게됩니까?

먼저해야 할 일은 sqlite 호출에 대한 모든 반환 코드를 확인하는 것입니다. 예를 들어 SQLite_ROW가 아닌 다른 단계는 처리하지 않습니다. 적어도 다른 사람들은 로그인하십시오. 또한 마무리 및 종료를 위해 다른 사람을 처리하거나 로깅하지 않습니다.

또한 SQL 문을 준비 (컴파일 중)하지만 저장하지는 않습니다. prepare_v2는 컴파일 된 명령문을 돌려줍니다. 멤버 변수로 저장하고 다시 사용하기 전에 리셋을 호출하십시오.

어떻게 닫아야하는지에 대한 구체적인 질문에 대답하려면 몇 가지 진술이 확정되지 않았을 수 있음을 고려해야합니다. 여기 내 가까운 방법입니다 : 당신이 더 많은 통찰력을 얻을 수 있도록

- (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; 
    } 
} 

마지막으로, 리턴 코드와 함께 더 많은 기록을 추가하는 것을 고려 (BTW, ENDebug는 NSLog를 통해 내 래퍼입니다).

희망이 있습니다.

+0

닫기를 실제로 제거 했으므로 다른 곳에서 데이터베이스를 닫을 수 있습니다. 일단 시간이 지나면 답을 자세히 보게 될 것이므로이 문제를 올바르게 처리하는 방법을 더 잘 이해할 수 있습니다 :) 답변 주셔서 감사합니다. – user969043

관련 문제