Почему в расширениях (extension) Swift нельзя хранить свойства (stored properties)?

«Почему в расширениях (extension) Swift нельзя хранить свойства (stored properties)?» — вопрос из категории Swift Core, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Расширения в Swift предназначены для добавления новой функциональности существующим типам, но не могут добавлять stored properties. Это ограничение связано с тем, что stored properties требуют выделения дополнительной памяти в структуре экземпляра, а расширения не могут изменять макет памяти существующего типа после его компиляции.

Почему это важно?

  • Безопасность и предсказуемость: Гарантирует, что расширение не нарушит работу существующего кода, изменив размер или расположение типа в памяти.
  • Производительность: Value-типы (структуры, перечисления) копируются по значению. Добавление stored property через расширение потребовало бы создания новой, несовместимой версии типа.

Альтернативы для хранения данных:

  1. Вычисляемые свойства (Computed Properties):
    extension UIView {
    var cornerRadius: CGFloat {
        get { layer.cornerRadius }
        set { layer.cornerRadius = newValue }
    }
    }
  2. Ассоциированные объекты (Associated Objects): Работает только для классов, наследующихся от NSObject. Использует Objective-C runtime.
    
    import ObjectiveC

extension UIView { private enum AssociatedKeys { static var customTag = "customTag" }

var customTag: String? {
    get {
        return objc_getAssociatedObject(self, &AssociatedKeys.customTag) as? String
    }
    set {
        objc_setAssociatedObject(self, &AssociatedKeys.customTag, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }
}

}


3. **Протоколы с реализацией по умолчанию:** Для добавления поведения, а не состояния.