PDF ファイルを表示するためのページ ビュー コントローラーを開発しています。別のスレッドで PDF ページから UIImage のレンダリングを開始し、レンダリングされたイメージを通知を通じてメイン スレッドに渡したいと考えています。
UIImage で自分のページをレンダリングし、画像の準備ができたら通知を投稿する別のメソッドを作成することから始めましたが、少なくとも今のところはまだメイン スレッドで実行しています。
- (void)generatePage:(int)pageNumber withSize:(CGSize)size {
UIImage *resultingImage;
CGFloat sizeRatio = size.width/size.height;
CGPDFDocumentRef pdfRef = [self PDFDocumentRef];
CGPDFPageRef myPageRef = CGPDFDocumentGetPage(pdfRef, pageNumber);
CGRect pageRect = CGPDFPageGetBoxRect(myPageRef, kCGPDFMediaBox);
CGFloat pdfHWRatio = pageRect.size.width/pageRect.size.height;
CGFloat pdfScale;
if (sizeRatio < pdfHWRatio) {
pdfScale = size.width/pageRect.size.width;
}
else {
pdfScale = size.height/pageRect.size.height;
}
pageRect.size = CGSizeMake(pageRect.size.width*pdfScale, pageRect.size.height*pdfScale);
pageRect.origin = CGPointZero;
UIGraphicsBeginImageContext(pageRect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBFillColor(context, 1.0,1.0,1.0,1.0);
CGContextFillRect(context,pageRect);
CGContextSaveGState(context);
CGContextTranslateCTM(context, 0.0, pageRect.size.height);
CGContextScaleCTM(context, pdfScale, -pdfScale);
CGContextDrawPDFPage(context, myPageRef);
CGContextRestoreGState(context);
resultingImage = UIGraphicsGetImageFromCurrentImageContext();
if (resultingImage) {
[pagesCache setObject:resultingImage
forKey:[self generateCacheNameWithSize:size
andPageNumber:pageNumber]];
NSDictionary *userInfo = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:
resultingImage,
[NSNumber numberWithInt:pageNumber],
nil]
forKeys:[NSArray arrayWithObjects:
CatalogRenderedPageImageKey,
CatalogRenderedPageNumberKey,
nil]];
NSNotification *note = [NSNotification notificationWithName:CatalogRenderPageNotification
object:self
userInfo:userInfo];
[[NSNotificationCenter defaultCenter] postNotification:note];
}
UIGraphicsEndImageContext();
CGPDFDocumentRelease(pdfRef);
}
通知は正常に取得され、UIImage は正しく取得されます (同じオブジェクト ID) が、UIImageView は空です。
- (void) imageLoaded:(NSNotification *)note {
NSDictionary *userInfo = note.userInfo;
NSNumber *pageNumber = [userInfo objectForKey:CatalogRenderedPageNumberKey];
if ([self.pageNumber isEqualToNumber:pageNumber]) {
UIImage *image = [userInfo objectForKey:CatalogRenderedPageImageKey];
self.image = image;
self.imageView.image = _image;
[[NSNotificationCenter defaultCenter] removeObserver:self name:CatalogRenderPageNotification object:self.catalog];
}
}
私は何が欠けていますか?UIImageView のストレージ プロパティを確認しましたが、UIImage で満たされています。
レンダリングされた画像をキャッシュに保存していることに気付いたかもしれませんが、そのキャッシュから画像を取得すると、UIImageView でそれらを見ることができるので、UIImage が正しく生成されていない可能性を無視します。
更新: 別のスレッドで generatePage の呼び出しを開始しました:
dispatch_async(dispatch_queue_create("renderingQueue", DISPATCH_QUEUE_CONCURRENT), ^{
[self generatePage:pageNumber withSize:size];
});
@ phyx23が提案したように、メインスレッドに通知を投稿します。現在は機能していますが、以前に機能しなかった理由はまだわかりません。
なぜこれが起こるのかについて誰でも考えを残すことができるように、私はそれを開いたままにしています.