Ответ
Нет, напрямую добавить хранимое свойство (stored property) в расширение (extension) в Swift нельзя. Расширения предназначены для добавления функциональности, а не для хранения состояния.
Что МОЖНО добавить в extension:
- Вычисляемые свойства (
computed properties) - Методы
- Инициализаторы (только convenience)
- Сабскрипты
- Вложенные типы
Пример вычисляемого свойства (разрешено):
extension Double {
var km: Double { return self * 1000.0 } // Вычисляется при каждом обращении
var cm: Double { return self / 100.0 }
}
let distance = 5.km // 5000.0
Обходные пути для хранения состояния:
1. Ассоциированные объекты (Objective-C runtime)
Позволяют привязать значение к объекту, но работает только с классами, наследующими от NSObject.
extension UIView {
private struct AssociatedKeys {
static var customIdentifier = "customIdentifier"
}
var customIdentifier: String? {
get {
return objc_getAssociatedObject(self, &AssociatedKeys.customIdentifier) as? String
}
set {
objc_setAssociatedObject(self, &AssociatedKeys.customIdentifier, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}
2. Использование глобальной словарной таблицы (с осторожностью)
private var storedProperties = [ObjectIdentifier: Any]()
extension MyClass {
var myProperty: Int {
get { storedProperties[ObjectIdentifier(self)] as? Int ?? 0 }
set { storedProperties[ObjectIdentifier(self)] = newValue }
}
}
3. Наследование или композиция (предпочтительный способ)
// Вместо extension, создайте подкласс
class EnhancedView: UIView {
var customStoredProperty: String = ""
}
// Или используйте композицию
struct ViewWrapper {
let view: UIView
var customStoredProperty: String
}
Вывод: Если вам нужно хранить состояние, расширение — неправильный инструмент. Рассмотрите редизайн через подкласс, композицию или (в крайнем случае) ассоциированные объекты.