Protocol extension does not seem to result in a variable change in the consumer?

Say you

protocol Able: class { var v:UIView? { get set } var x:CGFloat { get set } } 

then of course when you use Able,

enter image description here

if you forget "v" or "x" ...

this is mistake. It's good.

Do this:

 class ScreenThing: UIViewController, Able { @IBOutlet var v: UIView? var x: CGFloat = 0.0 } 

All right. It's great.

Forcibly, you specify "v" and "x" and really initialize them.

But. Try it...

 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() } } } 

Now the property has property p.

You can use p perfectly either in functions in Able or in functions in ScreenThing. It's great.

However.....

When will you do this .....

 class ScreenThing: UIViewController, Able { } 

You will not receive an error message.

You may forget to initialize "p" (it will work).

Indeed, you do not need to specify "p" as a variable (as you should with "v" and "x").

Why is this so?

This seems like a huge problem.

Is there anything else I have to do to force the compiler to force p to be executed, just as it naturally uses variables in protocols?




Another way to look at this question:

Given exactly my code above:

Is there a way to force the compiler to need an initializer for "p" in the user class?

For example.

I tried this ...

 class ScreenThing: UIViewController, Able { var p:P } 

But that does not work.

(Oddly enough, this is a compilation - I really don’t know what the hell it does! It seems to be a β€œdifferent” p from p in Extension. But in any case, it does not require an initializer.)

In short, again, is there anything that I could do or add above that will force the compiler to force me to initialize the pseudo-property-thing, as is usually the case when I put the property in the protocol like "x" or "v".

?

  • Perhaps I need to add some ordinary property to the protocol (for example, "pp") and somehow make p related to it somehow? Just a thought.



(Footnote - see this to understand the β€œclass” required in the above protocol.)




Answering my own question:

My confusion is that there is nothing to initialize. var p:P in the extension (with get and set code blocks) are just two functions.

There is nothing to initialize.

So, for example: in my additional question, I ask: "How to get the corresponding classes to initialize it when waking up?" It is pointless. In any case, one may ask: "How to make the corresponding classes necessarily" use these functions "when waking up?" - that has nothing to do with initialization.

Please note that my specific example code in the computed variable happens with a (unrelated) use of a variable that is not initialized, which leads to confusion.

+2
ios swift protocols
Jan 22 '17 at 22:47
source share
1 answer

You do not need to embed p in protocol utilities, as the protocol extension provided an implementation. This is an extension of the protocol.

Example:

 protocol P {} extension P { func greet() {print("hello")} } class C : P {} C().greet() 

Note that (1), which compiles although C does not declare greet and (2), it works, although C does not contain a greet implementation. This is because it is a protocol extension job.

+1
Jan 22 '17 at 22:58
source share



All Articles