2013-07-05 2 views
0

데이터베이스에 이미지를 저장하고 맞춤 카메라를 만들기 위해 av 캡처 세션을 사용 중입니다. 그러나 데이터베이스에 점점 더 많은 이미지를 저장하면 메모리 경고가 발생합니다.ios에서의 메모리 문제

데이터베이스에 이미지 저장을 중단하면 응용 프로그램이 제대로 작동합니다. 왜 그런 일이 발생합니까? 그것은 데이터베이스의 크기가 증가하기 때문에 발생합니까?

현재 코드 :

-(void)insert 
{ 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *path = [documentsDirectory stringByAppendingPathComponent:@"dbsqlite.sqlite"]; 

    if (sqlite3_open([path UTF8String], &database) == SQLITE_OK) 
    { 
     ////////\\ 

     for (jk=0; jk<[globalvalue count];jk++) 
     { 


      NSData *imgData = UIImagePNGRepresentation((UIImage *)[globalvalue objectAtIndex:jk]); 




      const char *query = "insert into color(img) values (?)"; 

      sqlite3_stmt *searchStatement2; 



      if (sqlite3_prepare_v2(database,query, -1, &searchStatement2, NULL) == SQLITE_OK) 
      { 
       sqlite3_bind_blob(searchStatement2,1, [imgData bytes], [imgData length], NULL); 
       if (sqlite3_step(searchStatement2) == SQLITE_DONE) 
       { 
        NSLog(@"saved"); 
       } 

    // 
    //   while (sqlite3_step(searchStatement2) == SQLITE_ROW) 
    //   { 
    //    NSString *name2 = [NSString stringWithUTF8String:(char *)sqlite3_column_text(searchStatement2, 0)]; 
    //    NSString *category2 = [NSString stringWithUTF8String:(char *)sqlite3_column_text(searchStatement2, 1)]; 
    //    NSLog(@"%@ is a %@ color", name, category); 
    // 
    // 
    //   } 
      } 
      sqlite3_finalize(searchStatement2); 
     } 
    } 

    [[[UIAlertView alloc]initWithTitle:@"alert" message:@"your query saved" delegate:nil cancelButtonTitle:@"cancel" otherButtonTitles: nil] show]; 
    sqlite3_close(database); 
} 

- (void)makeDBCopyAsNeeded 
{ 
    BOOL success; 
    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    NSError *error; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"dbsqlite.sqlite"]; 
    success = [fileManager fileExistsAtPath:writableDBPath]; 
    if (success) 
    { 
     return; 
    } 
    NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"dbsqlite.sqlite"]; 

    success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error]; 
    if (!success) 
    { 
     NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]); 
    } 
} 

-(void)readFromDatabase 
{ 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *path = [documentsDirectory stringByAppendingPathComponent:@"dbsqlite.sqlite"]; 


    if (sqlite3_open([path UTF8String], &database) == SQLITE_OK) 
    { 
     const char *sqlStatement="select img,rowID from color"; 
     sqlite3_stmt *compiledStatement; 

     if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL)==SQLITE_OK) 
     { 
      while (sqlite3_step(compiledStatement)==SQLITE_ROW) 
      { 

       NSData *data = [[NSData alloc] initWithBytes:sqlite3_column_blob(compiledStatement,0) length:sqlite3_column_bytes(compiledStatement,0)]; 
       if(data == nil) 
        NSLog(@"No image found."); 
       else 
       { 
        UIImage *personImage= [UIImage imageWithData:data]; 
        NSString *rowid1=[NSString stringWithFormat:@"%d", sqlite3_column_int(compiledStatement,1)]; 
        [rowid addObject:rowid1]; 
        [arrImageFromDataBase addObject:personImage]; 

        //    NSData *data  = [NSData dataWithBytes:sqlite3_column_blob(compiledStatement, 4) length:length]; 
        NSLog(@"%@",personImage); 
       } 

      } 
     } 
     sqlite3_finalize(compiledStatement); 
    } 
    sqlite3_close(database); 
    NSLog(@"contents of array%@",rowid); 
} 

그것은 조금 ... 혼란을 끼쳐 드려 미안하지만 정말 도움이 필요합니다!

+0

ARC를 사용합니까? 영어를 정리했습니다. – Raptor

+0

나는 호를 사용합니다. – mandeep

+5

데이터베이스에 이미지를 저장하는 것이 적절한 방법이 아닙니다. –

답변

-1

더 많은 이미지를 데이터베이스에 저장하면 메모리 경고가 발생합니다. 이미지 복사본을 만들어 데이터베이스에 저장하기 때문에 매우 분명합니다.

이미지를 라이브러리에 저장하고 데이터베이스 또는 plist에 저장하면됩니다.

+0

"매우 분명하지 않습니다". 데이터베이스에 이미지를 저장하는 것이 좋지 않더라도 OP에서 설명한 문제는 발생하지 않습니다. 문제가없고 메모리 경고가없는 메모리 관리 규칙의 기본 사항을 알고 있다면 "점점 더 많은"이미지를 데이터베이스에 저장할 수 있습니다. – LombaX

+0

그리고 예, ARC를 사용하면 메모리 관리 규칙을 잊어 버릴만한 좋은 이유가 아닙니다. :-) 여전히 중요합니다. – LombaX

1

다른 사람들이 쓴 것처럼 DB에 이미지를 저장하는 것은 좋지 않습니다. 하지만 이것은 문제가되지 않습니다 :-)

나는 for 루프가 있음을 알았습니다. 동시에 여러 이미지를 삽입 할 때 경고 메시지가 표시됩니까? 이미지를 "하나씩"삽입하더라도 이러한 문제가 발생합니까?

첫 번째 경우,이 사항을 고려하십시오

당신은 루프의 내부 UIImagePNGRepresentation 있습니다. 이 함수는 자동으로 릴리즈 된 NSData를 반환합니다. 자동 실행 풀은 현재 실행 루프 끝에서만 제거됩니다 (예 : 프로그램이 사용자에 의한 다음 동작 대기를 멈 추면). 그래서 함수에 의해 생성 된 모든 NSData는 실행 루프가 끝날 때까지 유지됩니다.

이러한 이유로 인해 한 번에 10 개의 이미지를 삽입하면 계산 끝에 만 제거되는 메모리 10 NSData가 복사됩니다. 100 개의 이미지를 삽입하면 같은 이야기가됩니다.

인스트루먼트 - 할당 툴을 사용하여이를 확인하십시오 (루프 중에 NSData가 차지하는 메모리가 증가하고 계산이 끝나면 즉시 감소합니다). 사실이라면 특정 자동 풀 풀 생성을 해결할 수 있습니다. 다음

UIImageWriteToSavedPhotosAlbum(UIImage *image, id completionTarget, SEL completionSelector, void *contextInfo);

이와

는 특정 오토 릴리즈 풀은 당신이 다음 코드를 사용할 수있는 라이브러리에 이미지를 저장해야 할 각 루프

for (jk=0; jk<[globalvalue count];jk++) 
{ 
    @autoreleasepool { 

     NSData *imgData = UIImagePNGRepresentation((UIImage *)[globalvalue objectAtIndex:jk]); 




     const char *query = "insert into color(img) values (?)"; 

     sqlite3_stmt *searchStatement2; 



     if (sqlite3_prepare_v2(database,query, -1, &searchStatement2, NULL) == SQLITE_OK) 
     { 
      sqlite3_bind_blob(searchStatement2,1, [imgData bytes], [imgData length], NULL); 
      if (sqlite3_step(searchStatement2) == SQLITE_DONE) 
      { 
       NSLog(@"saved"); 
      } 

      // 
      //   while (sqlite3_step(searchStatement2) == SQLITE_ROW) 
      //   { 
      //    NSString *name2 = [NSString stringWithUTF8String:(char *)sqlite3_column_text(searchStatement2, 0)]; 
      //    NSString *category2 = [NSString stringWithUTF8String:(char *)sqlite3_column_text(searchStatement2, 1)]; 
      //    NSLog(@"%@ is a %@ color", name, category); 
      // 
      // 
      //   } 
     } sqlite3_finalize(searchStatement2); 
    } 

} 
0

처음에 제거됩니다 라이브러리 경로를 SQL 데이터베이스에 저장하십시오. 이렇게하면 db의 크기가 줄어 듭니다. 또한 이미지 크기를 조정하여 이미지보기 에 표시하면 메모리 사용량이 줄어 듭니다.

+ (UIImage*)imageWithImage:(UIImage*)image 
      scaledToSize:(CGSize)newSize; 
{ 
    UIGraphicsBeginImageContext(newSize); 
    [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)]; 
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    return newImage; 
}