PDFKit leaks a Vision document-analysis pipeline per rendered PDFDocument on iPadOS 26 – and `PDFView` already has the switch to stop it

On iPadOS 26, PDFKit runs VNRecognizeDocumentsRequest over the pages of a PDFDocument when those pages are rendered. The analysis pipelines are never released.

Measured on an iPad Pro 12.9-inch 4th gen (iPad8,11), iPadOS 26.6, with a 61-page image-only scanned score: each newly-created-and-rendered PDFDocument costs about 2.7 OS threads and 20 MB, permanently. Repeatedly loading the same file from disk reached 153 threads and 1519 MB in under seven minutes, then died of an allocation failure.

Nothing releases it: not replacing PDFView.document, not deallocating the PDFView entirely, not releasing the PDFDocument, and not time. With every code path in the app stopped, the thread count does not fall — it continues to rise.

The stack

-[PDFView visiblePagesChanged:]
  → +[PDFPageAnalyzerV2 analyzePage:withBox:requestTypes:]
    → -[VNImageRequestHandler performRequests:gatheredForensics:error:]
      → -[VNRecognizeDocumentsRequest internalPerformRevision:inContext:error:]
        → -[VNDetector processUsingQualityOfServiceClass:options:regionOfInterest:…]
          → -[VNControlledCapacityTasksQueue dispatchSyncByPreservingQueueCapacity:]

Thread census at 1519 MB — 153 threads total, after 66 document loads:

66  PDFKit.PDFDocument.formFillingQueue
64  com.apple.VNRecognizeDocumentsRequestRevision1
10  ANEServicesThread

66 orphaned pipelines for 66 loads, all blocked on Vision's capacity limiter. The console also emits Invalid permutation index when reordering subregions. Index N must be less than number of subregions 1 continuously, with N increasing — and these keep arriving after all application activity has stopped.

Isolation

Each row is a separate run on the same device and OS, one variable changed. Counts are OS threads; baseline is 13.

ConfigurationResult
Page-stepping only on a stable document (~1000 visiblePagesChanged: events)No growth; footprint declines
Recreating PDFThumbnailView on every loadNo growth
Creating a PDFDocument and never rendering itNo growth
Creating + rendering, assigned to a PDFView+2.0 to +2.7 threads / +20 MB per load
Creating + rendering, never assigned to any PDFViewSame growth
Creating + rendering, entire PDFView destroyed and rebuilt per loadSame growth

Two points worth drawing out:

  1. The leak occurs with no PDFView involved at all — plain PDFPage.thumbnail(of:for:) or PDFPage.draw(with:to:) on a freshly created document is sufficient.
  2. Destroying the PDFView releases nothing. Whatever retains the analyses outlives every object the application can reach.

Also, for anyone who arrives here from the other PDFPageAnalyzerV2 threads: the usePageViewController(true, withViewOptions: nil) workaround does not help this. It reduces visiblePagesChanged: frequency, and page changes on a stable document leak nothing. The variable is newly rendered documents, not new pages.

The switch already exists

PDFView implements -setDocumentAnalysisEnabled: and -isDocumentAnalysisEnabled, plus -handleAnalysisCompletionOfPage:resultTypes:. None of these appear in any public header.

With document analysis disabled, the leak disappears completely — 28 consecutive document loads with zero thread growth, and after stopping, the process released down to 6 threads and 64 MB, below its own idle baseline. It also suppresses the leak for documents never assigned to that PDFView, so whatever the flag gates is not scoped to a single view.

For completeness, the per-page -setCandidateForOCR: / -setDidPerformOCR: accessors do not help: the writes land and read back correctly, and the analysis runs anyway. They appear to be state rather than policy.

Request

Either:

  1. Fix the leak — cancel and release analyses when the document or the view goes away; or
  2. Make documentAnalysisEnabled public on PDFView (or add an equivalent on PDFDocument).

Ideally, please do both.

The second costs Apple nothing: the property exists, it works, and it is exactly the control that is needed. Applications that render sheet music, engineering drawings, or any other content where document understanding provides no value are currently paying for it with unbounded memory growth and no supported way to decline.

Filed as FB24211659. Happy to share the isolation harness with anyone from the PDFKit team.

Related: 825803 (crash in PDFPageAnalyzerV2, FB22409977), 827781 (deadlock in the same class), 838272 / 837282 (PDFTileSurface over-release), 107007 (CGContextDrawPDFPage thread safety, open since 2018).

PDFKit leaks a Vision document-analysis pipeline per rendered PDFDocument on iPadOS 26 – and `PDFView` already has the switch to stop it
 
 
Q