Associated objects: состояние на чужом классе 🔑
🔥 Associated objects из рантайма Objective-C позволяют навесить хранимое свойство на класс, которым вы не владеете, — прямо из расширения, без наследования.
⚠️ И сразу главное: классическое объявление ключа в Swift 6 не компилируется. private static var analyticsKey: UInt8 = 0падает с «static property is not concurrency-safe because it is nonisolated global shared mutable state» (SE-0412). Лечится честно — nonisolated(unsafe) static var: сам байт никогда не читается и не пишется, используется только его адрес, так что отключение проверки тут не обман. А вот чего делать не надо, хотя советуют: UnsafeRawPointer(bitPattern: 1)! в качестве ключа. Рантайм сравнивает указатели по идентичности, и константу 1 с тем же успехом может выбрать любая другая библиотека в процессе.
💡 Про &Self.key можно не переживать: глобальные переменные и статические свойства дают неэфемерный указатель, если они хранимые и без наблюдателей — это прямо записано в документации компилятора по temporary pointers. Знаменитая «опасность амперсанда» — про локальные переменные. Работает на любых классах на платформах Apple, наследовать NSObject не нужно. На Linux рантайма ObjC нет вообще. И осторожно с .OBJC_ASSOCIATION_ASSIGN — это unowned-ссылка, она повиснет.