Building macOS App with Xcode 13 cause exception at launch in NSClassSwapper.initWithCoder

Hi,

We have our large (complex), production macOS application that has been building fine for many years in all previous versions of Xcode (9-12.4), up until the latest 13 release (none of the Xcode 13-betas appear to work either)

I get an NSException throw at launch on Xcode 13 and the following stack dump, but struggling to track down the cause and what might have changed in this version.

Our app is a hybrid Obj-C / Swift app and uses a legacy launch main.m file as we do some lower security checks on startup (still throws even with these check bypassed so not that)

I have checked the init functions are calling super.init as seen in another forum, but I can't find any docs on NSClassSwapper or what exactly it's purpose is.

The indicated 'MainMenuViewModel' class is a viewModel instantiated by the MainMenu.xib, and the MainMenu.xib is set as the 'main nib file base name' in the 'info.plist'. The class 'init' function appears to be getting called ok along with it super.

'MainMenuViewModel' is addressed via AppKit bindings from the MainMenu.xib and I get the feeling it might be something around the way we're creating the bindable object in the XIB that might have changed in the most recent Xcode, but can't find any documentation on that either.

Any ideas of how to debug further would be appreciated:



	0   CoreFoundation                      0x00007ff803420fcb __exceptionPreprocess + 242

	1   libobjc.A.dylib                     0x00007ff803186b9d objc_exception_throw + 48

	2   CoreFoundation                      0x00007ff803420e2f +[NSException raise:format:] + 189

	3   UIFoundation                        0x00007ff806ca4e77 UINibDecoderDecodeObjectForValue + 813

	4   UIFoundation                        0x00007ff806ca4b3d -[UINibDecoder decodeObjectForKey:] + 244

	5   AppKit                              0x00007ff805d950bb -[NSNibConnector initWithCoder:] + 97

	6   AppKit                              0x00007ff805d94ff6 -[NSNibOutletConnector initWithCoder:] + 404

	7   UIFoundation                        0x00007ff806ca4e05 UINibDecoderDecodeObjectForValue + 699

	8   UIFoundation                        0x00007ff806ca502a UINibDecoderDecodeObjectForValue + 1248

	9   UIFoundation                        0x00007ff806ca4b3d -[UINibDecoder decodeObjectForKey:] + 244

	10  AppKit                              0x00007ff805d93e19 -[NSIBObjectData initWithCoder:] + 168

	11  UIFoundation                        0x00007ff806ca4e05 UINibDecoderDecodeObjectForValue + 699

	12  UIFoundation                        0x00007ff806ca4b3d -[UINibDecoder decodeObjectForKey:] + 244

	13  AppKit                              0x00007ff805d93c05 loadNib + 301

	14  AppKit                              0x00007ff805d934ba +[NSBundle(NSNibLoading) _loadNibFile:nameTable:options:withZone:ownerBundle:] + 1268

	15  AppKit                              0x00007ff805d92ed1 -[NSBundle(NSNibLoading) loadNibNamed:owner:topLevelObjects:] + 201

	16  AppKit                              0x00007ff805d92caf +[NSBundle(NSNibLoading) loadNibNamed:owner:] + 394

	17  AppKit                              0x00007ff805d854fd NSApplicationMain + 566

	18  MyApp                           0x0000000106fef5be main + 190

	19  dyld                                0x000000010ba614d5 start + 421

)

2021-09-24 13:50:40.260716+1200 MyApp[11254:148063] *** Terminating app due to uncaught exception 'NSGenericException', reason: 'This coder is expecting the replaced object 0x7f964af11d80 to be returned from NSClassSwapper.initWithCoder instead of <MyApp.MainMenuViewModel: 0x7f964af11010>'

*** First throw call stack:

(

	0   CoreFoundation                      0x00007ff803420fcb __exceptionPreprocess + 242

	1   libobjc.A.dylib                     0x00007ff803186b9d objc_exception_throw + 48

	2   CoreFoundation                      0x00007ff803420e2f +[NSException raise:format:] + 189

	3   UIFoundation                        0x00007ff806ca4e77 UINibDecoderDecodeObjectForValue + 813

	4   UIFoundation                        0x00007ff806ca4b3d -[UINibDecoder decodeObjectForKey:] + 244

	5   AppKit                              0x00007ff805d950bb -[NSNibConnector initWithCoder:] + 97

	6   AppKit                              0x00007ff805d94ff6 -[NSNibOutletConnector initWithCoder:] + 404

	7   UIFoundation                        0x00007ff806ca4e05 UINibDecoderDecodeObjectForValue + 699

	8   UIFoundation                        0x00007ff806ca502a UINibDecoderDecodeObjectForValue + 1248

	9   UIFoundation                        0x00007ff806ca4b3d -[UINibDecoder decodeObjectForKey:] + 244

	10  AppKit                              0x00007ff805d93e19 -[NSIBObjectData initWithCoder:] + 168

	11  UIFoundation                        0x00007ff806ca4e05 UINibDecoderDecodeObjectForValue + 699

	12  UIFoundation                        0x00007ff806ca4b3d -[UINibDecoder decodeObjectForKey:] + 244

	13  AppKit                              0x00007ff805d93c05 loadNib + 301

	14  AppKit                              0x00007ff805d934ba +[NSBundle(NSNibLoading) _loadNibFile:nameTable:options:withZone:ownerBundle:] + 1268

	15  AppKit                              0x00007ff805d92ed1 -[NSBundle(NSNibLoading) loadNibNamed:owner:topLevelObjects:] + 201

	16  AppKit                              0x00007ff805d92caf +[NSBundle(NSNibLoading) loadNibNamed:owner:] + 394

	17  AppKit                              0x00007ff805d854fd NSApplicationMain + 566

	18  MyApp                           0x0000000106fef5be main + 190

	19  dyld                                0x000000010ba614d5 start + 421

)

libc++abi: terminating with uncaught exception of type NSException

*** Terminating app due to uncaught exception 'NSGenericException', reason: 'This coder is expecting the replaced object 0x7f964af11d80 to be returned from NSClassSwapper.initWithCoder instead of <MyApp.MainMenuViewModel: 0x7f964af11010>'

terminating with uncaught exception of type NSException

I encountered the same crash when loading my MainMenu.nib and I have found the reason of the crash.

I had several shared objects in the MainMenu.nib, such as NSDocumentController and others. These shared objects "init" are called twice. The first is from my own code and the second is from [NSClassSwapper initWithCoder].

In the first call, [super init] is called but in second call [super init] is not called because it is the shared object. The crash occurs when these shared object's second "init" call.

To work around this problem, I modified my code not to call the shared object "init" twice.

I hope this helps!

Satoshi Matsumoto

Building macOS App with Xcode 13 cause exception at launch in NSClassSwapper.initWithCoder
 
 
Q