diff --git a/ios/Runner/MpvPlayer/MpvPlayerCore.swift b/ios/Runner/MpvPlayer/MpvPlayerCore.swift index 465e7940..653a8b28 100644 --- a/ios/Runner/MpvPlayer/MpvPlayerCore.swift +++ b/ios/Runner/MpvPlayer/MpvPlayerCore.swift @@ -478,9 +478,14 @@ class MpvPlayerCore: NSObject { func dispose() { NotificationCenter.default.removeObserver(self) - if let mpv = mpv { - mpv_terminate_destroy(mpv) - self.mpv = nil + let mpvHandle = mpv + mpv = nil + + queue.sync { + if let handle = mpvHandle { + mpv_set_wakeup_callback(handle, nil, nil) + mpv_terminate_destroy(handle) + } } metalLayer?.removeFromSuperlayer() metalLayer = nil diff --git a/macos/Runner/MpvPlayer/MpvPlayerCore.swift b/macos/Runner/MpvPlayer/MpvPlayerCore.swift index 87849276..5fdfb6e9 100644 --- a/macos/Runner/MpvPlayer/MpvPlayerCore.swift +++ b/macos/Runner/MpvPlayer/MpvPlayerCore.swift @@ -428,9 +428,16 @@ class MpvPlayerCore: NSObject { // MARK: - Cleanup func dispose() { - if let mpv = mpv { - mpv_terminate_destroy(mpv) - self.mpv = nil + // Capture handle before clearing to avoid weak captures during deinit + let mpvHandle = mpv + mpv = nil + + // Tear down on the mpv queue to avoid races with wakeup callbacks still firing + queue.sync { + if let handle = mpvHandle { + mpv_set_wakeup_callback(handle, nil, nil) + mpv_terminate_destroy(handle) + } } metalLayer?.removeFromSuperlayer() metalLayer = nil