iOS26.x后PDFKit + PKCanvasView组合下的滑动放大极易崩溃

最常见的是这个: Thread 1 Queue : com.apple.main-thread (serial) #0 0x0000000190bcb3c4 in CFRelease.cold.2 () #1 0x0000000190a2c50c in CFRelease () #2 0x00000001d194ad38 in -[PDFTileSurface releaseSurface] () #3 0x00000001d194c230 in -[PDFTilePool releasePDFTileSurface:] () #4 0x00000001d194f618 in -[PDFPageLayerTile dealloc] () #5 0x0000000190a4778c in -[__NSArrayI_Transfer dealloc] () #6 0x000000018d5d57f8 in AutoreleasePoolPage::releaseUntil () #7 0x000000018d5d5684 in objc_autoreleasePoolPop () #8 0x000000019668d43c in -[UIScrollView setContentOffset:] () #9 0x000000018dd70918 in -[NSObject(NSKeyValueObservingPrivate) _changeValueForKeys:count:maybeOldValuesDict:maybeNewValuesDict:usingBlock:] () #10 0x000000018ddd1298 in -[NSObject(NSKeyValueObservingPrivate) _changeValueForKey🔑 key:usingBlock:] () #11 0x000000018ded5b28 in _NSSetPointValueAndNotify () #12 0x0000000196c49af0 in -[UIScrollView _smoothScrollSyncWithUpdateTime:] () #13 0x0000000196c491a0 in -[UIScrollView _smoothScrollWithUpdateTime:] () #14 0x0000000196c490b0 in -[UIScrollView smoothScrollDisplayLink:] () #15 0x000000026186a66c in -[DYDisplayLinkInterposer forwardDisplayLinkCallback:] () #16 0x00000001914cc77c in CA::Display::DisplayLinkItem::dispatch () #17 0x00000001914a4388 in CA::Display::DisplayLink::dispatch_items () #18 0x00000001914bb2b8 in CA::Display::DisplayLink::dispatch_deferred_display_links () #19 0x000000019671e2a8 in _UIUpdateSequenceRunNext () #20 0x000000019671b834 in schedulerStepScheduledMainSectionContinue () #21 0x00000002a437256c in UC::DriverCore::continueProcessing () #22 0x0000000190a3f1d8 in __CFMachPortPerform () #23 0x0000000190a81824 in CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION () #24 0x0000000190a8174c in __CFRunLoopDoSource1 () #25 0x0000000190a4c6e4 in __CFRunLoopRun () #26 0x0000000190a4b54c in _CFRunLoopRunSpecificWithOptions () #27 0x0000000235da7498 in GSEventRunModal () #28 0x0000000196744244 in -[UIApplication _run] () #29 0x00000001966af158 in UIApplicationMain () #30 0x00000001968bb618 in ___lldb_unnamed_symbol_1893835b0 () #31 0x0000000105a7a308 in static UIApplicationDelegate.main() () #32 0x0000000105a7a278 in static AppDelegate.$main() () #33 0x0000000105a7a3cc in main () #34 0x000000018d659c1c in start ()

Answered by DTS Engineer in 896871022

Thanks for the report, and for including the crash log.

I built a test on iOS 26 with the same combination: a PDFView with an overlaid PKCanvasView. I then stress-tested it on an iPad. It zoomed repeatedly to about 9x and back while running animated smooth scrolls. I also pinch-zoomed deep into a page and flick-scrolled quickly. I could not reproduce the crash using Apple frameworks alone.

Here is how I read your stack. The crash is an over-release. During a display-link-driven smooth scroll, setting the content offset drains an autorelease pool. That deallocates PDFKit tiles, and CFRelease then hits its error path (CFRelease.cold.2) while releasing a tile surface. That signature means an object is released one time too many.

One frame in the stack is not part of PDFKit, UIKit, or CoreAnimation: -[DYDisplayLinkInterposer forwardDisplayLinkCallback:]. This is code in your app, so you will know what it is. It intercepts and forwards the CADisplayLink callback that drives the smooth scroll where the crash occurs. It sits directly in the failing path and affects scroll timing. So a useful next step is to find out whether the crash still occurs without it.

Here is a way to isolate it:

  • Reproduce with DYDisplayLinkInterposer disabled or removed, so the display-link callback runs without it. If the crash stops, that isolates it to DYDisplayLinkInterposer. If it still crashes without it, that points at PDFKit.
  • If it still reproduces with only Apple frameworks, please file a report with Feedback Assistant. A small sample project that crashes with just PDFKit and PencilKit is the key piece. Include a sysdiagnose captured right after the crash and the symbolicated crash report, so the team can investigate directly.
  • It would also help to know how your PDFView and PKCanvasView are composited, in particular whether the canvas tracks the PDF's zoom and scroll. That matters in case the integration is involved.

Since heavy zoom and scrolling did not reproduce it here with PDFKit and PencilKit by themselves, isolating DYDisplayLinkInterposer is where I would start.

Please let me know what you find.

Thanks for the report, and for including the crash log.

I built a test on iOS 26 with the same combination: a PDFView with an overlaid PKCanvasView. I then stress-tested it on an iPad. It zoomed repeatedly to about 9x and back while running animated smooth scrolls. I also pinch-zoomed deep into a page and flick-scrolled quickly. I could not reproduce the crash using Apple frameworks alone.

Here is how I read your stack. The crash is an over-release. During a display-link-driven smooth scroll, setting the content offset drains an autorelease pool. That deallocates PDFKit tiles, and CFRelease then hits its error path (CFRelease.cold.2) while releasing a tile surface. That signature means an object is released one time too many.

One frame in the stack is not part of PDFKit, UIKit, or CoreAnimation: -[DYDisplayLinkInterposer forwardDisplayLinkCallback:]. This is code in your app, so you will know what it is. It intercepts and forwards the CADisplayLink callback that drives the smooth scroll where the crash occurs. It sits directly in the failing path and affects scroll timing. So a useful next step is to find out whether the crash still occurs without it.

Here is a way to isolate it:

  • Reproduce with DYDisplayLinkInterposer disabled or removed, so the display-link callback runs without it. If the crash stops, that isolates it to DYDisplayLinkInterposer. If it still crashes without it, that points at PDFKit.
  • If it still reproduces with only Apple frameworks, please file a report with Feedback Assistant. A small sample project that crashes with just PDFKit and PencilKit is the key piece. Include a sysdiagnose captured right after the crash and the symbolicated crash report, so the team can investigate directly.
  • It would also help to know how your PDFView and PKCanvasView are composited, in particular whether the canvas tracks the PDF's zoom and scroll. That matters in case the integration is involved.

Since heavy zoom and scrolling did not reproduce it here with PDFKit and PencilKit by themselves, isolating DYDisplayLinkInterposer is where I would start.

Please let me know what you find.

非常感谢你的回复

关于你提到的DYDisplayLinkInterposer,我确认不是我应用程序的代码。我在github上找到了它属于 PrivateFrameworks/GPUToolsCore.framework/DYDisplayLinkInterposer.h,这属于iOS-x-Runtime-Headers 提供的示例,这也是Apple 的代码 因此我无法分类,去使用你提供的方案尝试

其次,我可以提供更多细节给您 1、版本号上 26.4.2 (23E261), 26.5 (23F77) 最为高频 2、 PDFView 和 PKCanvasView 是如何组合的 我们使用PDFPageOverlayViewProvider(iOS 16+)将自定义视图叠加到每个PDF页面上。MEPDFEditView包含一个PKCanvasView以及其他几个子视图(形状图层、磁带视图、属性编辑器)。叠加视图在pdfView(_:overlayViewFor:)中创建,其生命周期由PDFKit管理——每个可见页面都有自己的叠加视图,由PDFKit自动缩放/定位。没有手动框架同步;PKCanvasView位于正确的PDF页面坐标的疊加中。 已经做的尝试有,只有pdfkit,无叠加视图,滑动流畅不崩溃 只有pdfkit,叠加视图是有PKCanvasView 滑动加载数据,会崩溃 低设备型号,如ipad8 ipad9很容易出现,一个500多页500M的笔记,基本上竖向滑动不到完整 当然我的页面上会有不少PKDrawing

我的疑问是,为什么同为ipad9 ipad0S18.x的设备就不会频繁触发 iOS26.x就会如此频繁,有哪些行为是上层应用可以做到的

iOS26.x后PDFKit + PKCanvasView组合下的滑动放大极易崩溃
 
 
Q