如何在iOS 16的PDFKit中禁用自动PDF分析?
iPadOS 16下PDFKit日志刷屏与资源消耗问题解决
一、屏蔽VKImageAnalyzer日志(调试阶段)
在Xcode控制台搜索框输入 -VKImageAnalyzer,即可过滤掉模拟器中频繁出现的[VKImageAnalyzer processRequest:] returned 0和[VKImageAnalyzer processRequest:] block returned NULL analysis日志,避免控制台刷屏。
二、禁用PDFKit自动图像分析(解决资源消耗)
由于PDFKit未提供公开API关闭iOS 16新增的图像分析功能,可尝试以下两种方案:
- 方案1:使用私有API(注意App Store审核风险)
在初始化PDFView后,调用私有方法关闭图像分析:#import <objc/runtime.h> // 初始化PDFView后执行 SEL selector = NSSelectorFromString(@"setEnableImageAnalysis:"); if ([pdfView respondsToSelector:selector]) { NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[pdfView methodSignatureForSelector:selector]]; BOOL enable = NO; [invocation setArgument:&enable atIndex:2]; [invocation setTarget:pdfView]; [invocation setSelector:selector]; [invocation invoke]; } - 方案2:静态渲染PDF为图片
如果乐谱PDF无需交互,可将PDF页面渲染为UIImage后展示,绕过PDFKit的自动分析逻辑:// 渲染PDF页面为图片 PDFPage *page = pdfDocument.pageAtIndex(pageIndex); CGRect pageRect = page.boundsForBox(kPDFDisplayBoxMediaBox); UIGraphicsBeginImageContextWithOptions(pageRect.size, NO, UIScreen.mainScreen.scale); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextTranslateCTM(context, 0, pageRect.size.height); CGContextScaleCTM(context, 1.0, -1.0); [page drawWithBox:kPDFDisplayBoxMediaBox toContext:context]; UIImage *pageImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); // 使用UIImageView展示图片 UIImageView *imageView = [[UIImageView alloc] initWithImage:pageImage];
三、解决CoreText字体警告
物理设备上的CoreText performance note警告,是因为PDFKit调用CTFontCreateWithName()时使用了字体名Times-Roman,而非对应的PostScript名称TimesNewRomanPSMT,可通过方法替换解决:
#import <CoreText/CoreText.h> #import <dlfcn.h> #import <objc/runtime.h> static CTFontRef (*originalCTFontCreateWithName)(CFStringRef name, CGFloat size, const CGAffineTransform* matrix); CTFontRef swizzledCTFontCreateWithName(CFStringRef name, CGFloat size, const CGAffineTransform* matrix) { // 替换字体名为正确的PostScript名称 if (CFStringCompare(name, CFSTR("Times-Roman"), 0) == kCFCompareEqualTo) { name = CFSTR("TimesNewRomanPSMT"); } return originalCTFontCreateWithName(name, size, matrix); } @implementation CoreTextFontFix + (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ void* coreTextHandle = dlopen("/System/Library/Frameworks/CoreText.framework/CoreText", RTLD_NOW); if (coreTextHandle) { originalCTFontCreateWithName = dlsym(coreTextHandle, "CTFontCreateWithName"); if (originalCTFontCreateWithName) { // 替换原函数实现 MSHookFunction((void*)originalCTFontCreateWithName, (void*)swizzledCTFontCreateWithName, (void**)&originalCTFontCreateWithName); } dlclose(coreTextHandle); } }); } @end
添加上述分类后,应用启动时会自动拦截字体创建请求,替换为正确的PostScript名称,消除警告并提升性能。
内容的提问来源于stack exchange,提问作者Ron Regev
相关产品推荐
相关产品推荐

