Ответ
Нет, напрямую добавить хранимое свойство (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
}
Вывод: Если вам нужно хранить состояние, расширение — неправильный инструмент. Рассмотрите редизайн через подкласс, композицию или (в крайнем случае) ассоциированные объекты.
Ответ 18+ 🔞
А, слушай, вот это классика, блядь! Прямо в точку попал. Сидишь такой, думаешь: «О, расширение — это же круто, сейчас я туда накидаю своих свойств, и будет мне счастье». А нихуя, ёпта!
Нет, нахуй, напрямую воткнуть хранимое свойство (stored property) в расширение (extension) в Swift — нельзя. Вообще, в рот меня чих-пых! Расширения — они как бы для функциональности, чтобы подкрутить, а не для того, чтобы там своё барахло хранить. Это как прийти в гости и начать в шкафу у хозяев свои носки держать — не по понятиям, блядь.
Что МОЖНО в extension впихнуть, не сломав систему:
- Вычисляемые свойства (
computed properties) — они же каждый раз на лету считаются, хуле. - Методы всякие.
- Инициализаторы, но только convenience, чтоб не выёбываться.
- Сабскрипты.
- Вложенные типы — ну, там свои enum'ы объявить.
Вот, смотри, пример вычисляемого — это легально:
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. Наследование или композиция (нормальный, человеческий путь, блядь!)
// Вместо того, чтобы расширение ебашить, сделай нормальный подкласс
class EnhancedView: UIView {
var customStoredProperty: String = "" // Вот, пожалуйста, храни на здоровье
}
// Или через композицию — заверни, как подарок
struct ViewWrapper {
let view: UIView
var customStoredProperty: String
}
Вывод, сука: Если тебе надо хранить состояние — расширение это не твой инструмент, это как молотком гвозди забивать. Либо делай нормальный подкласс, либо композицию используй, либо, в крайнем случае, эти ассоциированные объекты, если совсем припёрло. Но лучше по-человечески, а то потом сам не разберёшься, что где лежит.