We apologize for the inconvenience. The OS X and iOS architecture transitions demonstrate the two fundamental laws of ABI changes:
- Opportunities to break ABI compatibility are rare.
- Any opportunity to break ABI compatibility will suffer from severe schedule pressure.
The Objective-C ABIs have many problems that would have been improved with more time.
- We tried to get a “modern” ABI into i386, but the schedule was too tight and we lost time with some initial design ideas that didn’t pan out. x86_64 was also a tight schedule, but much of the work was already in place from the i386 attempt so we were able to get it done.
- Fixing BOOL was repeatedly not quite high enough priority.
- The 64-bit metadata structures have at least one field that is 64-bit by accident (protocol_list_t.count). There was miscommunication between the compiler and the runtime when the design was specified, and then it was never high enough priority to coordinate a fix later.
- armv7 uses setjmp-longjmp exceptions instead of “zero-cost” exceptions because that’s what GCC’s arm compiler used then and we didn’t have time to change it.
- The very first iPhone did not use a “modern” ABI. We knew we could break ABI compatibility at any time before 3rd party apps were supported, so we punted ABI modernization until after 1.0.
- Non-fragile ivars on iPhone had a fragility bug in the compiler. (You don’t see non-fragile ivars doing their thing until the *second* release, except for deliberate testing. We didn’t test enough.) Luckily the bad case was narrow and the miscompiled code was detectable by inspecting binaries in the App Store, so we were able to ask all of the affected apps to recompile with a fixed compiler before the next iPhoneOS version shipped.
If we tried to rush Swift ABI stability out the door for Swift 3 we would certainly end up with deliberate or accidental flaws like the above. Being able to take the time to get it right is a rare luxury.