2011-10-20 2 views
1

거대하고 이상한 문제 : 사진을 찍어 내 이름 (일 + 임의 번호)을 내 앱 안에 저장하고 내 " imagePath "NSString 변수입니다. 그것은 나에게 EXC_BAD_ACCESS을 제공하지만 다른 방법을 사용하려고 할 때, 나는 sqlite가 데이터베이스에이 주소를 저장해야합니다 을 잘,이 방법의 끝까지 내가 전역 변수이다 "IMAGEPATH의 콘텐츠에 액세스 할 수 있습니다. ""(IMAGEPATH, 또한 나는 %의 @ NSLog @ ");"와 그 내용을 참조하려고합니다.이 crashs을 을 몇 가지 아이디어NSString으로 인해 앱이 다운되는 경우 ...

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { 
[picker dismissModalViewControllerAnimated:YES]; 

    int r = arc4random() % 9999; 
    NSDate *date = [NSDate date]; 
    NSString *photoName = [dateNameFormatter stringFromDate:date]; 
    photoName = [photoName stringByAppendingString:[NSString stringWithFormat:@"%d", r]]; 

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    imagePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@" %@.png", photoName]]; 

    UIImage *picture = [info objectForKey:UIImagePickerControllerOriginalImage]; 

    // ----- CODE FOR SCALE THE IMAGE ----- // 

    // ----- ----- - END CODE - ----- ----- // 

    NSData *webData = UIImagePNGRepresentation(picture); 
    CGImageRelease([picture CGImage]); 
    [webData writeToFile:imagePath atomically:YES]; 
    NSLog(@"%@", imagePath); 
    imgPicker = nil; 
} 

답변

2

문제는이 때문이다. 즉, 이벤트 루프 사이클의 끝에서 발생하는 NSAutoreleasePool 드레인의 일부로 해제 될 것입니다. 당신이 메모리 을 생성하지 않지만 당신이 주위을 중지 할 때문에

, 당신은 retain로해야 함 :

당신이 결정해야 무엇
[imagePath retain]; 

유지 메모리의이 작품은 을 할 수있을 때입니다을 발표했습니다. 앱이 어떻게 작동하는지 정확히 알지 못하기 때문에 결정은 귀하에게 달려 있습니다.이 객체가 만 피커 컨트롤러로 오래 살아남을해야하는 경우,

if (imagePath) { 
    [imagePath release]; 
} 
imagePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@" %@.png", photoName]]; 
[imagePath retain]; 

을 당신은 dealloc 방법을 해제해야합니다 : 당신은이 메서드를 1 회 이상 호출하는 경우, 당신은 아마 등을 출시 할 것 이 응용 프로그램의 수명 동안 생존하는 경우는

- (void)dealloc { 
    [imagePath release]; 
    // Other releases 
    [super dealloc]; 
} 

그렇지 않으면, dealloc에서 방출에 대해 걱정하지 마십시오. (하지만 두 번 이상 할당하면 할당하기 전에 해제해야합니다.) 응용 프로그램이 종료되면 메모리가 OS에서 회수됩니다.

+0

좋아요! 그게 완벽 했어! 고마워. 한 가지 더 : 이미지의 전체 경로를 사용하여 이미지를 UIImage로 어떻게 설정할 수 있습니까? (이것은 단지 ->/Users/Sk *****/라이브러리/응용 프로그램 지원/iPhone Simulator/4.3.2/Applications/15977219-DEFE-407A-BB80-72E188E18DD2/Documents/20-10-20111746). png) – Oiproks

+0

별도의 질문으로 질문해야합니다. 나는 대답 할 수있다. 그러나 코멘트 섹션은 그 장소가 아니다. :) –

-1
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *imgPathWithOutDir = [[NSString alloc] initWithFormat:@" %@.png", photoName]; 
    imagePath = [documentsDirectory stringByAppendingPathComponent:imgPathWithOutDir]; 

    UIImage *picture = [info objectForKey:UIImagePickerControllerOriginalImage]; 

    // ----- CODE FOR SCALE THE IMAGE ----- // 

    // ----- ----- - END CODE - ----- ----- // 

    NSData *webData = UIImagePNGRepresentation(picture); 
    CGImageRelease([picture CGImage]); 
    [webData writeToFile:imagePath atomically:YES]; 
    NSLog(@"%@", imagePath); 
    [imgPathWithOutDir release]; 
    imgPicker = nil; 
+1

이 코드에 괄호가 너무 많습니다! (편집 후에도!) – Simon

1

당신이 시도 할 수있다 ...

?
imagePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@" %@.png", photoName]]; 

[imagePath retain]; 

// Your code// 

[webData writeToFile:imagePath atomically:YES]; 
NSLog(@"%@", imagePath); 

[imagePath release]; 
+1

동일한 메소드가 아닌 dealloc에서 해제하십시오. – Ishu

+0

이 대답은 잘못되었습니다. OP는 ** imagePage **를 인스턴스 변수로 저장하여 다른 메소드에서 사용할 수 있습니다. 생성 직후에 여기에서 놓으면 객체가 할당 해제되어 ivar이 손상된 상태가됩니다. 또한 @Ishu,이 메소드가 여러 번 호출되는 경우 dealloc에서 ** release ** 호출을 남겨두면 메모리 누수가 발생할 수 있습니다. –

+0

@craig 다음은 [imagePath release]와 유사해야합니다; [imagePath = [documentsDirectory stringByAppendingPathComponent : [NSString stringWithFormat : @ "% @. png", photoName]]; [imagePath 유지]; – Ishu

1

세트 NSZombieEnabled, MallocStackLogging 및 디버거에서 guard malloc.

(gdb) info malloc-history 0x543216 

가 충돌의 원인이 된 객체의 주소로 0x543216 교체, 당신은 훨씬 더 유용한 스택 추적을 얻을 것이다 그것을 당신이 정확하게 도움이 될 것입니다 그런 다음 응용 프로그램이 충돌 할 때, gdb를 콘솔에서이 입력 문제를 일으키는 코드의 정확한 줄

See this article for more detailed instructions.

0

당신이 IMAGEPATH에 저장할 값은 당신의 소유가 아닙니다. stringByAppendingPathComponent:에서 자동 게시 된 객체를 가져 오는 중입니다. 당신은 그것을 가지고 있습니다. (Btw은 : 당신은 iOS5를 아래에서 개발하고 있습니까?) IMAGEPATH 이후

0

글로벌 변수입니다. 클래스에있는 모든 부분에 액세스 할 수 있지만 그 시간에 값을 저장하면 유지되지 않습니다.

후이 값을받은, 방법에서 꺼집니다, 그것은 방출을 간다. 그래서 그것을 사용하십시오.

이 줄

imagePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@" %@.png", photoName]]; 

[imagePath retain]; 

당신이 다른 시간을 유지 호출하지 않는 동안되지 않은 방법의 dealloc에 ​​놓습니다.

imagePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@" %@.png", photoName]]; 

오토 릴리즈 객체에 imagePath를 할당합니다