Допустим, выРасширение протокола, похоже, не приводит к изменению переменной в потребителе?
protocol Able: class {
var v:UIView? { get set }
var x:CGFloat { get set }
}
тогда, конечно, когда вы используете Способный,
, если вы забыли "V" или "х" ...
это ошибка. Это хорошо.
Так что это:
class ScreenThing: UIViewController, Able {
@IBOutlet var v: UIView?
var x: CGFloat = 0.0
}
Все хорошо. Замечательно.
Принудительно, что вы указываете «v» и «x» и действительно инициализируете их.
Но. Попробуйте это ...
var _H: UInt8 = 0
protocol Able: class {
}
extension Able where Self:UIViewController {
var p:P {
get {
return objc_getAssociatedObject(self, &_H) as! P
}
set {
objc_setAssociatedObject(self, &_H, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
__setter()
}
}
}
Able сейчас имеет свойство p.
Вы можете использовать p отлично либо в функциях в Able, либо в функциях в ScreenThing. Замечательно.
Однако .....
Когда вы сделаете это .....
class ScreenThing: UIViewController, Able {
}
вы не получить ошибку.
Вы можете забыть инициализировать «p» (он сработает).
Действительно, вам не нужно указывать «p» в качестве переменной (как вы должны с «v» и «x»).
Почему это так?
Это похоже на огромную проблему.
Есть ли что-то другое, что я должен сделать, чтобы заставить компилятор обеспечить соблюдение «p», так же как он, естественно, обычно применяет переменные в протоколах?
Другой способ посмотреть на этот вопрос:
Учитывая именно мой код выше:
есть способ для обеспечения компилятор нужен инициализатор для «р» в потребителе класс?
Например.
Я попытался это ...
class ScreenThing: UIViewController, Able {
var p:P
}
Но это не работает.
(Как это ни странно, это компиляция - на самом деле я не знаю, что, черт возьми, это делает! Кажется, это «другое» p из p в Extension. Но в любом случае это не требует необходимости для инициализатора.)
Вкратце, снова есть что-то, что я мог бы сделать или добавить выше, что заставит компилятор принудительно заставить меня инициализировать псевдо-свойство-вещь, как это обычно бывает, когда я поместите свойство в протокол, например «x» или «v».
?
- Возможно, мне нужно добавить в протокол обычное свойство (например, «pp») и каким-то образом сделать p связанным с этим каким-то образом? Просто мысль.
(Сноска - см this понять ": класс", необходимый в протоколе выше.)
Отвечая на мой собственный вопрос:
Мой путанице выше что есть ничего не инициализировать. var p:P
в расширении (с блоками get и set code) - это просто две функции.
Инициализировать нечего.
Так например: в моем дополнительном вопросе я спрашиваю: «Как заставить соответствующие классы инициализировать его при пробуждении?» Это бессмысленно. Во всяком случае, можно спросить: «Как заставить соответствующие классы обязательно« использовать эти функции »при пробуждении?» - что не имеет ничего общего с инициализацией.
Обратите также внимание на то, что мой конкретный пример кода в вычисленной переменной происходит (не связанно) с использованием переменной, которая не инициализируется, что приводит к путанице.
Я не уверен, что вы ожидаете от компилятора - 'p' не является требованием к протоколу (и даже если это так, вы уже дали ему реализацию по умолчанию в качестве вычисленного свойства), так что вы ожидая, что компилятор обеспечит выполнение вами в «ScreenThing»? – Hamish
Swift - относительно новый язык, с компилятором, полным ошибок в угловых случаях. Я бы опубликовал отчет об ошибках и посмотрел, что Apple должна сказать. – dasblinkenlight
Эй @hamish - Я не так эксперт, как вы, мужчина. Но простой факт заключается в том, что - глядя на конкретный пример - вам не нужно инициализировать его вообще. Обратите внимание, что приведенный пример приведет к сбою при запуске. Я никогда не видел примера get-set idiom, в Swift, где вы можете «не инициализировать его» (!) Итак, я тщательно рассмотрю, что вы сказали, и изучите вопрос человека! – Fattie