CGContextDrawPDFPage crashed and does not free memory
i have a problem with my pdf generation in iOS.
I am loading a pdf and generating a list (tableview) of thubmnails. Each
thumbnail will be generated if it is displayed (tableView:-
(UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath).
The generation of an thumbnail will be done by a NSBlockOperation in a
NSOperationQueue with max 1 concurrent operation.
Sometimes the app crashes with exc_bad_access at CGContextDrawPDFPage.
Additionally the CGContextDrawPDFPage does not release the used memory and
caches it. I try to clear the cache by reopening the pdf with
CGPDFDocumentCreateWithURL which is wrapped in a NSObject.
Generation:
- (void)loadThumbnailsFromPage:(int)fromPage toPage:(int)toPage {
if (self.thumbnailOperationQueue == nil) {
self.thumbnailOperationQueue = [NSOperationQueue new];
self.thumbnailOperationQueue.maxConcurrentOperationCount = 1;
[NSTimer scheduledTimerWithTimeInterval:3.0 target:self
selector:@selector(test) userInfo:nil repeats:YES];
} else {
// [self.thumbnailOperationQueue cancelAllOperations];
}
NSBlockOperation *blockOperation = [NSBlockOperation
blockOperationWithBlock:^{
PDFWrapper *pdf = [[PDFWrapper alloc] initWithPDFURL:self.pdfURL];
int pages = CGPDFDocumentGetNumberOfPages(pdf.pdfRef);
int from = fromPage;
int to = toPage;
if (from > to) {
to = from;
}
if (from > pages) {
from = pages;
}
if (to > pages) {
to = pages;
}
for (int i = fromPage; i <= toPage; i++) {
NSString *imageName = [NSString
stringWithFormat:@"%d.thumb.png", i];
NSString *fullPathToFile = [self.thumbDocPath
stringByAppendingPathComponent:imageName];
if (![[NSFileManager defaultManager]
fileExistsAtPath:fullPathToFile]) {
[ThumbnailLoader loadThumbnailForPage:i pdf:pdf
filePath:fullPathToFile];
}
if (self.didLoadPage != nil) {
dispatch_async(dispatch_get_main_queue(), ^{
self.didLoadPage(i, fullPathToFile);
});
}
}
[pdf close];
pdf = nil;
}];
[self.thumbnailOperationQueue addOperation:blockOperation];
}
(there some testing stuff within so ignore it.
[PDFWrapper close] releases the CGPDFDocumentRef and the initialization
opens it.
The thumbnail generation itself
+ (void)loadThumbnailForPage:(int)pageIndex pdf:(PDFWrapper *)pdf
filePath:(NSString *)filePath {
@synchronized(pdf) {
CGPDFPageRef page = CGPDFDocumentGetPage(pdf.pdfRef, pageIndex);
if (!page) {
return;
}
CGSize thumbSize = CGSizeMake(THUMB_WIDTH, THUMB_HEIGHT);
CGRect thumbRect = CGRectMake(0, 0, THUMB_WIDTH, THUMB_HEIGHT);
UIGraphicsBeginImageContext(thumbSize);
CGContextRef context = UIGraphicsGetCurrentContext();
//prevent releasing while drawing
CGPDFPageRetain(page);
CGContextRetain(context);
CGContextTranslateCTM(context, 0.0, thumbSize.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextSetGrayFillColor(context, 1.0, 1.0);
CGContextFillRect(context, thumbRect);
CGAffineTransform pdfTransform =
CGPDFPageGetDrawingTransform(page, kCGPDFCropBox, thumbRect, 0,
true);
CGContextConcatCTM(context, pdfTransform);
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
CGContextSetRenderingIntent(context, kCGRenderingIntentDefault);
CGContextDrawPDFPage(context, page);
CGContextRelease(context);
CGPDFPageRelease(page);
UIImage *thumbnailImage =
UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
@autoreleasepool {
NSData *imageData = UIImageJPEGRepresentation(thumbnailImage,
30);
if (imageData) {
NSLog(@"WROTE TO:%@", filePath);
if (![imageData writeToFile:filePath atomically:NO])
NSLog(@"ERROR: Thumb Didnt Save"); //COMMENT OUT TO
DISABLE WRITE
}
imageData = nil;
thumbnailImage = nil;
}
}
}
I hope anyone can help me.
Best,
Richard
This is really a nice and informative, containing all information and also has a great impact on the new technology.ios training institute in chennai
ReplyDeleteios developer training in chennai