2010-06-21 4 views
2

iOS 용 Quartz PDF API를 사용할 때 충돌 문제가 발생합니다. 현재 SDK 4.0 GM 시드로 컴파일 중이며 3.2 iPad에서 실행 중입니다 (동일한 결과를 가진 3.2 SDK를 사용해 보았습니다).Quartz PDF API에서 메모리 부족 오류가 발생합니다.

내가 사용하는 모든 코드는 표준 Apple Quartz 문서 및 인터넷상의 다양한 출처를 기반으로합니다. 그래서 나는 이미지가 크게 다르거 나 틀린 것을 할 수 없다.

"시뮬레이트 메모리 경고"기능을 사용하는 동안 코드는 시뮬레이터 (모든 버전, 유니버셜 앱)에서 완벽하게 실행됩니다. 누수 도구를 사용했는데 누수가 발견되지 않았습니다. 또한 Build and Analyze는 아무것도 발견하지 못합니다. 내 라이브러리에 충돌이나 낮은 메모리 로그가 남아 있지 않습니다.

이 모든 것이이 장치의 메모리가 부족하다고 생각하게 만듭니다. 이것은 약 50 %의 pdf 페이지를 실행 한 후에 발생하며 약 35 %는 일부 이미지 (일부 전체 페이지 일부 아이콘)를가집니다. 특정 페이지에서 충돌하지 않습니다. 내가로드하는 pdf는 약 75 페이지와 3.5MB입니다.

나는이 사이트와 인터넷에서 유사한 문제를 살펴본 후 아래 코드에서 몇 가지 조언을 적용했습니다. 이제 모든 페이지 턴마다 pdf 문서 참조를 릴리스하고 더 이상 페이지 참조를 유지/해제하지 않습니다. 또한 CGImages를 사용하여 UIGraphicsGetImageFromCurrentImageContext 함수를 사용하는 것에서 이미지 스와핑을 단순화했습니다. 나는 새로 할당 된 temp 인스턴스 ([[UIImageView alloc] iniWithImage:UIGraphicsGetImageFromCurrentImageContext()] 사용)로 pdfImgView를 완전히 대체하고, pdfImgView에 setter를 사용하고 온도를 릴리스하는 것을 포함하여 이미지를 전환하기위한 다양한 구현을 시도했다. 모든 유사 콘텐츠는 누수 및 분석기 테스트를 통과하지만 여전히 동일한 충돌 동작을 나타냅니다.

PDF에서 완전히 벗어나기 전에 내가 시도해야 할 것이 있습니까, 아니면 제가 빠뜨린 것입니까? 첫 번째로드와 페이지를 교환하는 인터페이스 핸들러에서 호출되어

보기 컨트롤러 코드 : 구성하고 상황에 PDF 페이지를 그리는 데 사용

[self drawPage]; 

// ...animation code...simple CATransition animation...crashes with or without 

// scrollView is a UIScrollView that is a subview of self.view 
[scrollView.layer addAnimation:transition forKey:nil]; 
// pdfImgView is a UIImageView that is a subview of scrollView 
pdfImgView.image = UIGraphicsGetImageFromCurrentImageContext(); 

drawPage 방법 :

[CFURLRef pdfURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("BME_interior.pdf"), NULL, NULL); 
pdfRef = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL); // instance variable, not a property 
CFRelease(pdfURL); 
CGPDFPageRef page = CGPDFDocumentGetPage(pdfRef, currentPage); 

CGRect box = CGPDFPageGetBoxRect(page, kCGPDFMediaBox); 
// ...setting scale and imageHeight, both floats... 

if (UIGraphicsBeginImageContextWithOptions != NULL) { 
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(self.view.frame.size.width, imageHeight), NO, 0.0); 
} else { 
    UIGraphicsBeginImageContext(CGSizeMake(self.view.frame.size.width, imageHeight)); 
} 
CGContextRef context = UIGraphicsGetCurrentContext(); 
NSLog(@"page is %d, context is %d, pdf doc is %d, pdf page is %d", currentPage, context, pdfRef, page); // all prints properly 

// ...setting up scrollView for new page, using same instance... 

CGContextTranslateCTM(context, (self.view.frame.size.width-(box.size.width*scale))/2.0f, imageHeight); 
CGContextScaleCTM(context, scale, -1.0*scale); 

CGContextSaveGState(context); 
CGContextDrawPDFPage(context, page); 
CGContextRestoreGState(context); 

CGPDFDocumentRelease(pdfRef); 
pdfRef = NULL; 
+0

. (계측기는 누출을 점검 할 수있을뿐 아니라 실제 객체를 검사 할 수 있습니다.) 무엇입니까? 대답은 그것에 달려 있습니다. – Yuji

+0

내 라이브 할당량은 ~ 12MB를 넘지 않으며 갑자기 위 아래로 내려갑니다. 유휴 상태 일 때 보통 3-5MB 정도 떨어져 있습니다. 메모리 모니터 도구를 사용하면 내 응용 프로그램의 가상 메모리가 충돌하기 전에 200MB가지나 갔다는 것을 알 수 있습니다. 메모리 경고 수준 1에서 수준 2를 확인한 다음 몇 페이지가 지나면 충돌이 발생합니다. 그래서 UIImage 또는 UIImageView에 의해 캐싱 된 이미지가 공개되어야하지만 분명히 뭔가가 여전히 매달려 있습니다. – bensnider

답변

1

아하! 새로운 이미지 컨텍스트를 시작하기 전에 UIGraphicsEndImageContext();을 추가하여 충돌을 해결했습니다. 난

0

CGContextSetInterpolationQuality(context, kCGInterpolationHigh); 
CGContextSetRenderingIntent(context, kCGRenderingIntentDefault); 

CGContextDrawPDFPage 전에 내 비슷한 문제를 해결 호출 ... 이제 메모리 경고를하지 않습니다.

크레딧은 요한이 대답에 간다 : 당신은 객체가 사용 가능한 모든 메모리를 먹고있는보고 악기를 사용할 수 있습니다 CGContextDrawPDFPage taking up large amounts of memory

관련 문제