fix: very rare crash on quit

This commit is contained in:
lwouis committed 2026-05-24 21:14:39 +02:00
1 parent b6af54425e
commit 007edc624e
5 files changed
+35

No files matched your search

+1
View File
@@ -1 +1,2 @@
#import "AppCenterApplication.h"
#import "ObjCExceptionCatcher.h"
+6
View File
@@ -259,6 +259,7 @@
D04BAD2A7F2E8BF64EE982E9 /* TextArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA7C836A8CE8C0B8D128B /* TextArea.swift */; };
D04BAD451966B43720120D2E /* Menubar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BAD905546AA93E5117B0A /* Menubar.swift */; };
D04BADA3F2DAB820D6FC6E75 /* AppCenterApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = D04BA48BC82D3060C3A1AB11 /* AppCenterApplication.m */; };
6E800CF06EE430DCCF9CE47B /* ObjCExceptionCatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = E7DD4D4CA23EE28B22048CE6 /* ObjCExceptionCatcher.m */; };
D04BADCDA9F9A6C3D6499877 /* SystemPermissions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA7C6F2519091717F4B4E /* SystemPermissions.swift */; };
D04BADE4DDF7597749FB13BD /* SettingsWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA099FA155FB4D517D66B /* SettingsWindow.swift */; };
D04BAE8B16A06A10E2FA94DE /* AccessibilityEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA8FDCF137D892114F5F3 /* AccessibilityEvents.swift */; };
@@ -528,6 +529,7 @@
D04BA4336B6004A0A99849AD /* package.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = package.json; sourceTree = "<group>"; };
D04BA459034C1885CA43A807 /* LICENCE.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = LICENCE.md; sourceTree = "<group>"; };
D04BA48BC82D3060C3A1AB11 /* AppCenterApplication.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppCenterApplication.m; sourceTree = "<group>"; };
E7DD4D4CA23EE28B22048CE6 /* ObjCExceptionCatcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCExceptionCatcher.m; sourceTree = "<group>"; };
D04BA49E45BFFF3D9FC60E43 /* HyperlinkLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HyperlinkLabel.swift; sourceTree = "<group>"; };
D04BA4A26987F67DD94C827F /* AboutTab.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AboutTab.swift; sourceTree = "<group>"; };
D04BA4A621A8A15660F973C1 /* KeyboardEvents.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyboardEvents.swift; sourceTree = "<group>"; };
@@ -584,6 +586,7 @@
D04BAAE6E6823304D66B74F8 /* update_website.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = update_website.sh; sourceTree = "<group>"; };
D04BAAF760E3A8A22BDA84D6 /* appcast.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = appcast.xml; sourceTree = "<group>"; };
D04BAAF79737A0673502FEB5 /* AppCenterApplication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppCenterApplication.h; sourceTree = "<group>"; };
3F9B638CE7C1DF9BD655C52B /* ObjCExceptionCatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjCExceptionCatcher.h; sourceTree = "<group>"; };
D04BAB703998DAD0EC9A6F4A /* ko */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = ko; path = Localizable.strings; sourceTree = "<group>"; };
D04BAB74451B79FE18B8BEDF /* BackgroundWork.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackgroundWork.swift; sourceTree = "<group>"; };
D04BAB7AC7316FA7117B071E /* pt-BR */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = Localizable.strings; sourceTree = "<group>"; };
@@ -813,6 +816,8 @@
E70C8A1100000000000SP001 /* SparkleDelegate.swift */,
D04BAAF79737A0673502FEB5 /* AppCenterApplication.h */,
D04BA48BC82D3060C3A1AB11 /* AppCenterApplication.m */,
3F9B638CE7C1DF9BD655C52B /* ObjCExceptionCatcher.h */,
E7DD4D4CA23EE28B22048CE6 /* ObjCExceptionCatcher.m */,
);
path = vendors;
sourceTree = "<group>";
@@ -1882,6 +1887,7 @@
AECF000000000000000000A2 /* Endpoints.swift in Sources */,
AECF000000000000000000B2 /* Secrets.swift in Sources */,
D04BADA3F2DAB820D6FC6E75 /* AppCenterApplication.m in Sources */,
6E800CF06EE430DCCF9CE47B /* ObjCExceptionCatcher.m in Sources */,
D04BAA16F21AC41A23DDA63D /* ControlsTab.swift in Sources */,
DD6771EE8ACE714C2599FEB7 /* OverrideClickResolver.swift in Sources */,
D04BADE4DDF7597749FB13BD /* SettingsWindow.swift in Sources */,
+10
View File
@@ -100,6 +100,16 @@ class Application: NSObject {
deinit {
Logger.info { self.debugId }
// `NSRunningApplication` KVO removal can throw NSInternalInconsistencyException
// ("Failed to register for runningApplicationNotificationCallback") — an Apple bug
// when the underlying notification XPC service has gone away (e.g. observed app
// terminated, or we are quitting). Pre-emptively invalidate inside an ObjC try/catch;
// the subsequent automatic ivar destroy of `kvObservers` is then a no-op.
let observers = kvObservers
kvObservers = nil
ObjCExceptionCatcher.catching {
observers?.forEach { $0.invalidate() }
}
}
/// Symmetric counterpart to the `CFRunLoopAddSource` in `observeEvents()`. See
+5
View File
@@ -0,0 +1,5 @@
@import Foundation;
@interface ObjCExceptionCatcher : NSObject
+ (void)catching:(NS_NOESCAPE void (^)(void))block;
@end
+13
View File
@@ -0,0 +1,13 @@
#import "ObjCExceptionCatcher.h"
@implementation ObjCExceptionCatcher
+ (void)catching:(NS_NOESCAPE void (^)(void))block {
@try {
block();
} @catch (NSException *exception) {
NSLog(@"Swallowed NSException: %@ — %@", exception.name, exception.reason);
}
}
@end