Say you
protocol Able: class {
var v:UIView? { get set }
var x:CGFloat { get set }
}
then of course, when you use Able,
if you forget "v" or "x"...
it is an error. That's good.
So do this:
class ScreenThing: UIViewController, Able {
@IBOutlet var v: UIView?
var x: CGFloat = 0.0
}
All's well. That's great.
It is enforced that you specify "v" and "x" and indeed initialize them.
But. Try this...
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 now has a property p.
You can use p perfectly either in functions in Able, or, in functions in ScreenThing. That's great.
However.....
When you do this.....
class ScreenThing: UIViewController, Able {
}
you do not get an error.
You can forget to initialize "p" (it will crash).
Indeed you don't have to specify "p" as a variable (as you must with "v" and "x").
Why is it so?
This seems like a huge problem.
Is there something different I have to do, to, make the compiler enforce "p", just as it of course normally enforces variables in protocols?
Another way to look at this question:
Given exactly my code above:
is there a way to enforce the compiler to need an initializer for "p" in the consumer class?
For example.
I tried this...
class ScreenThing: UIViewController, Able {
var p:P
}
But that doesn't work.
(Strangely, that compiles - actually I don't know what the hell it's doing! It seems to be a "different" p from the p in the Extension. But in any event it doesn't enforce the need for an initializer.)
In short, again, is there something I could do or add, above, that would make the compiler enforce me initializing the pseudo-property-thing, just as of course it normally does when I put a property in the protocol such as "x" or "v".
?
- maybe I have to add some ordinary property in the protocol (like "pp"), and somehow make p related to that in some way?? Just a thought.
(Footnote -- see this to understand the ": class" needed in the protocol above.)
Answering my own question:
My confusion above is that there is nothing to initialize. The var p:P
in the extension (with the get and set code blocks) is simply two functions.
There's nothing to initialize.
So for example: in my extra question, I ask "how to force conforming classes initailize it on wake up?" That is meaningless. If anything, one could ask: "how to force conforming classes be sure to 'use those functions' on wake up?" - which has nothing to do with initialization.
Note too that my specific example code in the computed variable, happens to (unrelatedly) use a variable that doesn't get initialized - leading to confusion.