Greetings,
With MacOS 15 Sequoia, Apple updated key-value-observations in such a way, that an unremoved observation by a now deallocated object will no longer cause an exception, when the observed object triggers said observation.
While this is fundamentally a positive change, the issue comes with the fact, that this change affects systems based on the version of their operating system and not the version of the operating system of the build system.
Many of our customers use old operating system versions and old hardware - meaning they can't easily update. Since we need to use up to date Xcode versions to develop for newer systems, our developers tend to have rather new OS versions.
This means, that we are increasingly facing bugs which only happen in customer systems but not in most developer (or QA) systems.
Currently, we still can use earlier OS versions with Xcode to fix these bugs, but once the used Xcode versions no longer support MacOS 14 or below this will become a major hurdle.
Are there known solutions to this issue?
We are currently attempting to swizzle observer adding and removal in order to fix the problem for old systems as well, but this has proven to be quite difficult and unstable. Since any weakly held property in the middle of an observation keypath can cause crashes, one would have to split up observations into multiple subobservations, which is less simple than it sounds, due to custom implementations of addObserver (such as there seems to be in array controller proxies) and collection operators.
Thanks for any suggestions!
Are there known solutions to this issue?
What sort of solution are you looking for?
It seems like this is something you’d address using static analysis. That is, some sort of linter rule that looks for classes that use KVO and checks that their deinitialiser undoes the observation.
The other way to find such problems is with testing. If you support old systems you really should be testing your app on those old systems. You could add an option to run your tests with the standard memory debugging tools, and specifically zombies, which is good and finding issues like this.
Finally, trying to ‘fix’ this at runtime is a mug’s game. KVO’s implementation is… well… exciting, and monkeying around with its internals is likely to cause more problems that it solves.
WARNING If you ignore my advice and decide to tackle this at runtime, make sure these Silly Runtime Trick™ are disabled on macOS 15 and later. That’ll help limit your compatibility liability.
Oh, I had one other idea here: You could file an enhancement request requesting an option, like an environment variable, that forces KVO to trap in this situation. That way you could enable this on modern systems and catch problems that way.
If you do file such a ER, please post your bug number, just for the record.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"