2012-07-22 4 views
0

데이터베이스에 삽입해야하는 행이 많습니다. 필요한 정보가 탭으로 구분 된 약 50 개의 .txt 파일을 다운로드합니다. 나는 데이터를 파싱하고 동일한 방법으로 데이터베이스에 삽입한다. 내가 별도의 방법으로 있었을 때,에 시뮬레이터 내 27 "은 메모리가 부족하기 때문에 아이맥이 충돌 할 방법은 다음과 같습니다.FMDB에 데이터를 삽입하면 장치에 충돌이 발생하여 대부분의 메모리 효율적인 방법으로 sqlite에 데이터를 삽입 할 수 있습니다.

- (BOOL)insertDataWithFileName:(NSString *)fileName { 
    NSLog(@"%s %@", __FUNCTION__, fileName); 
    if (_db == nil) { 
     return NO; 
    } 
    // Get the data from the file 
    NSData *data = [[NSData alloc] initWithContentsOfFile:[[self applicationDocumentsDirectory] stringByAppendingPathComponent:fileName]]; 
    NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 

    // Parse each line by newlines first 
    NSArray *lines = [responseString componentsSeparatedByString:@"\n"];   

    NSString *ID = [[fileName componentsSeparatedByString:@"."] objectAtIndex:0]; 

    // Set up the database insert statement 
    NSString *tableName = @"Hardcodedtablename"; // remove after prototype 
    BOOL oldshouldcachestatements = _db.shouldCacheStatements; 
    [_db setShouldCacheStatements:YES]; 
    [_db beginTransaction]; 
    NSString *insertQuery = [NSString stringWithFormat:@"INSERT INTO %@ values(null, ?, ?, ?, ?, ?, ?, ?);", tableName]; 
    BOOL success; 

    // Parse each line by tabs 
    for (NSString *line in lines) { 
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
     NSArray *fields = [line componentsSeparatedByString:@"\t"]; 

     // Need to check since some of the .txt files have an empty newline at the EOF. 
     if ([fields count] == NUM_VARIANT_FIELDS) { 
      NSNumber *loc = [NSNumber numberWithInteger:[[fields objectAtIndex:0] integerValue]];  
      NSString *carType = [fields objectAtIndex:1]; 
      NSString *model = [fields objectAtIndex:2]; 
      NSString *AA = [fields objectAtIndex:7]; 
      NSString *BB = [fields objectAtIndex:8]; 

      NSNumber *freq = [[fields objectAtIndex:11] isEqualToString:@""] ? [NSNumber numberWithDouble:-1.0] : [NSNumber numberWithDouble:[[fields objectAtIndex:11] doubleValue]]; 

      NSArray *argArray = [[NSArray alloc] initWithObjects:ID, loc, carType, model, AA, BB, freq, nil]; 

      success = [_db executeUpdate:insertQuery withArgumentsInArray:argArray]; 
      [argArray release]; 

     } 
     [pool drain]; 
    } 

    [_patientAnnotatedDatabase commit]; 
    [_patientAnnotatedDatabase setShouldCacheStatements:oldshouldcachestatements]; 

    return success; 
} 

당신은 루프, 실제로 돈 내에서 볼 수 있듯이 ' 배열에있는 모든 파일이 \ t에 의해 분리 된 후에 필요합니다. for 루프에서 메모리 풋 프린트를 줄이기 위해 autorelease 풀을 설정합니다. 가장 큰 파일에는 27 만 개의 행이 있습니다. 약 50 개 정도의 파일이 있습니다. 따라서 장치에 2 개의 파일이있는 경우 오류가 발생합니다. 오류 메시지는 표시되지 않습니다 ..

아니면 서버 측에서 데이터베이스를 만들고 대신 장치에 데이터베이스를 다운로드해야합니까? 서버에서 장치로 데이터베이스를 다운로드 한 경우 FMDB는 이러한 테이블을 한 DB에서 다른 DB로 전송할 수있는 기능을 지원합니까? 내가 인터넷 검색을하는 동안 그와 같은 것을 찾을 수 없었습니다. 감사!

답변

0

정말 데이터를 사용하는 대상에 따라 다릅니다. 때

270,000 rows * 25 chars/row * 50 files * 1 byte/char = 321 Mb of RAM 

내가 25 개 문자/행 부분에 대해 추측하고있어,하지만 : 당신은 검색하거나 당신이 정말로 그것을 모두 필요합니다 몇 가지 목적을 위해, 당신은 기본적으로이 많은 메모리를 사용하고 그것을 사용하는 경우 100MB 이상의 메모리를 사용하고 있으며, 많은 메모리를 사용하고 있습니다. 그러나 iPad 에는에 약 1GB의 RAM이 있으므로 사용할 수있는 메모리 양 안에있는 것처럼 보일 수 있습니다. 하지만, NSArrays 및 SQLite FMDB (다른 NSObject와 마찬가지로)를 저장하는 데 사용하는 때문에 캡슐화 된 데이터는 iPad에서 실행되는 다른 프로세스에 추가 될 때 1GB가 넘을 수 있습니다.

그래서이 메모리가 모두 문제가 될 수 있습니다. 이 데이터를 처리 할 수있는 웹 서버에이 모든 데이터를 저장하는 것이 더 좋을 수 있으며, 상기 서버를 통해 원하는 모든 기능을 호출하는 것이 좋습니다. 아마도 훨씬 빨라 졌을 것이고 업데이트가 필요할 경우 데이터를 쉽게 조정할 수있게 될 것입니다. 또한 충분한 RAM이없는 iPhone과 같은 기기에서 앱을 사용할 수 있습니다.

데이터의 양이 문제인 경우 솔루션은 위의 해결 방법입니다. 그러나 나는 여전히 iPad가 300MB 이상의 RAM을 처리 할 수 ​​있다고 생각하므로 문제는 코드에있을 수 있습니다. 가장 작은 "범위를 벗어난"배열 오류로 인해 프로그램이 실패 할 수 있으므로 파일에서 데이터를 배열로 분리 할 때 특히 모든 데이터에 올바르게 액세스하고 있는지 확인하십시오.

메모리 프로파일 러를 활성화 한 상태에서 코드를 실행 해 보았습니까? 새 Xcode에서이 앱을 활성화하려면 "실행"버튼을 누른 상태에서 "프로필러"옵션을 선택할 수 있습니다. 이 앱은 앱에서 사용중인 메모리 양을 보여 주므로 1GB 미만인지 확인 할 수 있습니다.

+0

예 Allocations 템플릿 세트가있는 Instruments에서 실행했습니다. 나는 파일을 파싱 할 때 메모리가 커지는 것을보고, 파싱을 끝내고 for 루프가 끝나면 즉시 축소되는 것을 볼 수있다.NSBundle에 데이터를 포함 시키면 iPad에서 정보를 올바르게 처리 할 수 ​​있습니다. 나는 네이티브 경험이 지금처럼 빨리 될 수 있도록 장치에 보관하는 것을 선호합니다. 당신의 분석에서, 아마 코드 일 것 같은데? iMac에서 여러 번 실행했는데 문제가 없습니다. 흠 ... 웹 서버를 통해 데이터베이스를 전송하는 것은 옵션이 아닙니다. – Crystal

+0

그건 정말 이상한 ... 응용 프로그램이 NSBundle의 데이터와 잘 작동한다면 이는 메모리 문제가 아니라는 것을 의미합니다. 앱이 언제 충돌하나요? 특정 파일의로드가 중단되면 해당 파일에 문제가있을 수 있습니다. – pop850

0

불행히도 이전 계획을 추적하기 위해 NSZombieEnabled를 설정했습니다. 그것이 꺼지면, 지금이 순간에 부서지는 것 같지 않습니다.

관련 문제