2010-05-18 58 views
1

將PDF頁轉換爲UIImages時,我總是收到內存警告。如何在Objective-C的PDF文件中生成UIImages時處理內存警告?

似乎有一些泄漏或其他東西吃我的記憶。

使用儀器沒有給我任何有用的細節。

我使用下面的函數生成一個PDF文件中的圖像:

- (UIImage*)pdfImage:(NSString*)pdfFilename page:(int)page { 

CFURLRef pdfURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)pdfFilename, kCFURLPOSIXPathStyle, false); 
CGPDFDocumentRef pdfRef = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL); 
CFRelease(pdfURL); 

CGPDFPageRef pdfPage = CGPDFDocumentGetPage(pdfRef, page); 
CGRect pdfPageSize = CGPDFPageGetBoxRect(pdfPage, kCGPDFBleedBox); 

float pdfScale; 
if (pdfPageSize.size.width < pdfPageSize.size.height) { 
    pdfScale = PDF_MIN_SIZE/pdfPageSize.size.width; 
} 
else { 
    pdfScale = PDF_MIN_SIZE/pdfPageSize.size.height; 
} 


CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
CGContextRef context = CGBitmapContextCreate(NULL, 
      pdfPageSize.size.width*pdfScale, 
      pdfPageSize.size.height*pdfScale, 
      8, 
      (int)pdfPageSize.size.width*pdfScale * 4, 
      colorSpace, 
      kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 
CGColorSpaceRelease(colorSpace); 
// CGContextClipToRect(context, pdfPageView.frame); 

// CGPDFPageRetain(pdfPage); 
CGAffineTransform transform = aspectFit(CGPDFPageGetBoxRect(pdfPage, kCGPDFBleedBox), 
      CGContextGetClipBoundingBox(context)); 
CGContextConcatCTM(context, transform); 
CGContextDrawPDFPage(context, pdfPage); 
// CGPDFPageRelease (pdfPage); 

CGImageRef image = CGBitmapContextCreateImage(context); 
CGContextRelease(context); 

UIImage *finalImage = [UIImage imageWithCGImage:image]; 
CGImageRelease(image); 
CGPDFDocumentRelease(pdfRef); 


return finalImage; 
} 

我釋放文件和其他一切,所以這裏可能是問題?

感謝您的幫助!

+0

什麼是「記憶警告」,以及如何「接收」它們? – 2010-05-18 23:18:21

+0

通過xcode中的gdb調試器控制檯接收到「內存警告」,如下所示: 2010-05-19 00:13:07.806 xx [5020:207]接收到內存警告。級別= 1 2010-05-19 00:13:10.017 xx [5020:207]接收到內存警告。級別= 2 ..並導致在該應用程序中發生內存崩潰:) – favo 2010-05-18 23:29:14

回答

1

泄漏有時會產生誤報,甚至可能泄漏不在您的代碼中的泄漏。分析儀(shift-option-A)說什麼?我會先信任它。另一件要檢查的問題是,泄漏問題是否會隨着移植到新版本的模擬器而消失。

+0

泄漏發生在設備上(使用os 3.2)本身,而不是模擬器。 我某種程度上無法分析類,因爲它是因爲我聲明瞭接口內的變量(「不能聲明變量insode @interface或@protocol」)的分析錯誤,因爲它被跳過。 – favo 2010-05-18 23:34:59

+1

我會把變量帶出界面。該分析儀值得進行一些重組。 – 2010-05-19 00:11:16

+0

我已經這樣做了,並用分析器玩了一下。你的權利,絕對值得重組!但是這並沒有給我任何幫助。我在其他地方收到了可能的泄漏,但是我沒有發佈任何代碼序列,並導致問題。 – favo 2010-05-19 17:54:28

2

好,每次你調用這個方法,假設你存結果四周,自動釋放的對象

UIImage *finalImage = [UIImage imageWithCGImage:image]; 

分配會消耗一些內存。 iPhone是相當無情的,所以如果你有這些圖像中的一些(甚至只有一個),以及一些相當大的pdf,你可以很容易地達到內存限制。

我剛剛在使用3000 x 2000像素的圖片,並一直打到內存警告,直到我開始平鋪它。

所以,

1)您的PDF頁面有多大?

2)你是否讓他們周圍? 3)如果你註釋掉上面提到的那一行,而只是返回nil,你是否仍然彈出內存警告?

+0

我將通過這個函數生成的頁面添加到一個UIScrollView,使用UIImageViews在每次加載新的PDF時進行更新。 改變它返回零似乎解決了這個問題。 在調用該函數的函數中釋放返回的圖像: UIImage * tstImg = [self pdfImage:filename page:1]; UIImageView * tstView = [[UIImageView alloc] initWithImage:tstImg]; [..] [tstImg release]; ..讓我錯誤的消息發送到一個釋放實例。 如果這是內存問題,我應該如何正確釋放對象,如果它不是自動釋放,手動釋放會導致錯誤? – favo 2010-05-18 23:54:08

+0

PDF文件大約爲1024x768像素,一次顯示1-6頁。 – favo 2010-05-18 23:55:10

+0

我會盡量減少周圍的頁面。也許是當前,下一個和前一個。如果生產它們需要一段時間,那麼你可以嘗試將它們緩存在磁盤上,而不是內存中。 回覆:上面的發佈問題,您不需要在引用的情況下釋放tstImg,因爲它在從pdfImage:page:方法返回時標記爲autorelease,並且它將由imageview保留。 該版本可能會導致它被交易,使imageview留下垃圾,並等待發生崩潰。 當您釋放圖像視圖時,它將被正確清理 - snydely_whiplash – 2010-05-19 08:09:26

相關問題