2013-06-23 3 views
1

나는 XML 피드를 네트워크에서 가져 와서 파싱하고 sqlite db에 저장 한 다음 사용자에게 표시하는 ios 앱을 만들고있다.ios - 데이터베이스 저장 시간이 오래 걸린다.

내 XML 피드 긴 1700 라인입니다 : http://www.paulshin.ca/yunatube/res/en.xml

이 내 응용 프로그램이 작동하도록되어 방법이다.

  1. 사용자는 XML 객체를 통해
  2. 앱이 네트워크
  3. 사용 XML 파서 및 루프를 통해 XML을 가져옵니다 응용 프로그램을 실행이 완료되면에서 SQLite는 DB
  4. 에 표시 항목을 각 항목을 저장 테이블 뷰 ..

그러나 단계 2는 5 초 미만이고 단계 3은 20 초 정도 소요됩니다. 그 이유는 각 항목을 데이터베이스에 저장하는 데 시간이 걸리기 때문입니다.

다음

나는 3 단계에 사용하는 것입니다

TBXMLElement * elemRoot = 전무, * 유튜브 = 전무, * maincateg = 전무, * categ = 전무, * 클립 = 무기 호;

// maincatg 
    NSString *mcTitle = nil; 
    // catge 
    NSString *cTitle = nil; 
    // clip 
    NSString *title = nil, *url = nil, *note = nil; 

    elemRoot = tbxml.rootXMLElement; 

    if (elemRoot) { 
     youtube = [TBXML childElementNamed:@"youtube" parentElement:elemRoot]; 
     maincateg = [TBXML childElementNamed:@"maincateg" parentElement:youtube]; 

     while (maincateg) { 
      mcTitle = [TBXML valueOfAttributeNamed:@"type" forElement:maincateg]; 

      categ = [TBXML childElementNamed:@"category" parentElement:maincateg]; 
      while (categ) { 
       cTitle = [TBXML valueOfAttributeNamed:@"title" forElement:categ]; 

       clip = [TBXML childElementNamed:@"clip" parentElement:categ]; 
       while (clip) { 
        title = [TBXML valueOfAttributeNamed:@"title" forElement:clip]; 
        url = [TBXML valueOfAttributeNamed:@"url" forElement:clip]; 
        note = [TBXML valueOfAttributeNamed:@"note" forElement:clip]; 

        //TODO 
        if (![note isEqualToString:@"0"]) { 
         // save pared data to persistent 

         title = [title stringByReplacingOccurrencesOfString:@"&" 
                   withString:@"&"]; 
         cTitle = [cTitle stringByReplacingOccurrencesOfString:@"&" 
                   withString:@"&"]; 

         DatabaseManager *database = [DatabaseManager getInstance]; 
         **[database addDataToTable:mcTitle title:title url:url category:cTitle];** 
        } 
        clip = clip -> nextSibling; 
       } 
       categ = categ -> nextSibling; 
      } 

      maincateg = maincateg -> nextSibling; 
     } 

위에서 알 수 있듯이 중첩 루프가 있으며 각 항목은 DB에 addDataToTAble(); * 으로 줄을 제거하면 (즉, 각 루프 이후에 항목을 저장하지 않으면) 매우 빠르게 작동합니다. 그러나 *으로 줄을 그대로두면 오랜 시간이 걸립니다. 각 항목을 저장할 때

또한이 기능 같아
-(void) addDataToTable: (NSString*)table 
      title: (NSString*)title 
       url:(NSString*)url 
      category:(NSString*)category 
{ 
    sqlite3_stmt *statement; 
    const char *dbpath = [_databasePath UTF8String]; 

    if (sqlite3_open(dbpath, &_yunatubeDB) == SQLITE_OK) { 

     NSString *insertSQL = [NSString stringWithFormat: @"INSERT INTO %@ (TITLE, URL, CATEGORY) VALUES (\"%@\", \"%@\", \"%@\")", table, title, url, category]; 

     const char *insert_stmt = [insertSQL UTF8String]; 
     sqlite3_prepare_v2(_yunatubeDB, insert_stmt, 
          -1, &statement, NULL); 
     if (sqlite3_step(statement) == SQLITE_DONE) { 
      //   NSLog(@"Successfully added to DB"); 
     } else { 
      NSLog(@"Failed to add data to DB"); 
     } 
     sqlite3_finalize(statement); 
     sqlite3_close(_yunatubeDB); 
    } 
} 

잠시 소요되며, 저장 시간에 축적하기 때문에, 결국 최대 20 초가 소요 다음과 같이

이 함수이다. 나는 안드로이드와 비슷한 알고리즘을 사용하며 빠르게 작동하지만 돈이 오래 걸리는 이유는 모르겠다. 이 처리 시간이 앱 스토어의 앱 리뷰에 부정적인 영향을 줄 수 있는지 궁금합니다. 나는 안드로이드에서 비슷한 방법을 사용하고 그것은 매우 빨리 거기에서 작동합니다 .. 4 초 미만. 왜 그렇게 오래 걸릴지 모르겠다. 내가 뭔가 잘못하고 있는거야?

도움을 주시면 감사하겠습니다.

+0

모든 행을 하나의 INSERT sratent에 삽입 할 수 있습니다. 참조 : http://stackoverflow.com/questions/1609637/is-it-possible-to-insert-multiple-rows-at-a-time-in-an-sqlite-database –

+0

언제나 db를 엽니 다. 끼워 넣다? 전체 루프 전에 한 번만 해보는 것은 어떨까요? –

답변

1

루프 전에 SQLite 트랜잭션을 시작한 다음 나중에 끝내십시오. 트랜잭션을 수동으로 시작/중지하지 않으면 SQLite는 모든 쓰기 작업을 자동으로 처리하므로 매우 느립니다.

0

20 초가 지나면 사과 리뷰가 나오지만 앱을 좋은 평가를받지 못합니다.

항목을 찾을 때마다 데이터베이스에 기록합니다. 구문 분석이 끝나면 db에 작성해야합니다.

관련 문제