fix: 並列AVIFデコード時のクラッシュを修正#6
Merged
Merged
Conversation
Nukeが複数スレッドでAVIF画像をデコードする際、ColorSpaceキャッシュの Dictionary CoW競合でクラッシュしていた問題をNSLockで保護して修正。 あわせてYUV422のypCrDiffBufferのバッファ参照ミスと、 ダミーCrプレーンの確保サイズ不整合も修正。 Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
There was a problem hiding this comment.
Pull request overview
Fixes a crash that occurred when Nuke decoded multiple AVIF images concurrently. The root cause was non-thread-safe Dictionary caches for CGColorSpace shared across decode threads; this PR serializes access via NSLock. Two unrelated bug fixes in the YUV buffer code are also included.
Changes:
- Introduce a private
ColorSpaceCacheenum guarding RGB/monochromeCGColorSpacedictionaries withNSLock, and remove the file-scope mutable dictionaries. - Collapse the duplicated
(UNKNOWN, UNKNOWN)switch cases in bothcalcColorSpaceRGBandcalcColorSpaceMonochrome. - Fix two typos in the buffer pipeline: dummy Cr allocation size now uses
MemoryLayout<UInt8>(matching Cb), and YUV422ypCrDiffBuffernow points atypCrDiffBufferDatainstead ofypCbDiffBufferData.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
Nuke-Avif-Plugin/ColorSpace.swift |
Adds NSLock-guarded ColorSpaceCache, routes both cache helpers through it, deduplicates UNKNOWN switch arms. |
Nuke-Avif-Plugin/Buffer/BufferExtraction.swift |
Fixes dummy Cr buffer allocation size to UInt8 (was Int). |
Nuke-Avif-Plugin/Buffer/BufferConversion.swift |
Fixes YUV422 Cr diff buffer to reference ypCrDiffBufferData instead of ypCbDiffBufferData. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
k20rs141
approved these changes
Jun 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Nuke で AVIF 画像を複数枚同時に読み込むと、まれにクラッシュする問題を修正しました。
アプリ側の設定ミスではなく、ライブラリ内部の ColorSpace キャッシュがスレッドセーフでなかったことが原因です。Glenwood など、漫画ページの prefetch を多用するアプリで報告されていました。
このライブラリは何をしているか
本プラグインは Nuke の画像読み込みパイプラインに AVIF デコーダを追加し、.avif ファイルを
UIImageに変換します。アプリ側でAvifImageDecoder.enable()をすることで、Nukeのデコーダリストにプラグインのデコーダが追加されるので、受け取った画像ファイルがavifだった場合プラグインのデコーダが使用される
クラッシュはどこで起きていたか
スタックトレース上、③ の最終段階(CGImage 生成時の ColorSpace 取得) で落ちていました。
Crashlytics では
swift_isUniquelyReferenced付近、CGImageCreation.swift:15として記録されていました。クラッシュ箇所では何をしているのか
このライブラリはavifファイルから得られたピクセル情報などから、CGImageを作っています
この方法でCGImageを作る上で必要な要素の一つとして"CGColorSpace"があります
Nuke-Avif-Plugin/Nuke-Avif-Plugin/CGImageCreation.swift
Lines 13 to 31 in 4149dba
ColorSpace(色空間)は、ピクセル値を「どんな色として解釈するか」を定義する情報です。
AVIF ファイルには ICC プロファイルや CICP(色原色・トーンカーブ)としてこの情報が含まれており、デコード時に CGColorSpace として CGImage に付けます。
付けないと OS が別の色空間(例: デバイス RGB)で解釈するため、意図した色と表示がずれることがあります。
avifファイルに保存されていた色情報からColorSpaceを生成する役割を"calcColorSpaceMonochrome" or "calcColorSpaceRGB"が担っています。そこで今回はクラッシュしていました。
なぜクラッシュしたか
ColorSpaceを アプリ全体で共有する Dictionary キャッシュ から取得していました。
Nuke は画像 decode を 複数スレッドで並列実行 します。
漫画アプリのように 複数ページを prefetch する と、初回 decode 時に複数スレッドが同時にキャッシュへ書き込み、Dictionary の内部状態が壊れてクラッシュしていました。
今回の修正内容
1. ColorSpace キャッシュのスレッドセーフ化(本修正)
NSLockでキャッシュへのアクセスを直列化し、並列 decode しても安全にしました。デコード確認結果↓
https://www.notion.so/link-u/Nuke-avif-plugin-36e5e0d3605d8098bb2df1c3802bb586?source=copy_link#36e5e0d3605d809aae55c040a243941e
2. その他のバグ修正(副次)
BufferConversion.swiftBufferExtraction.swiftColorSpace.swift