协议扩展似乎没有在消费者中强制执行变量?

2024-01-10

Say you

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

当然,当你使用 Able 时,

如果你忘记了“v”或“x”......

这是一个错误。那挺好的。

所以这样做:

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。

您可以在 Able 的函数中或 ScreenThing 的函数中完美地使用 p。那太棒了。

然而.....

当你这样做时......

class ScreenThing: UIViewController, Able {
}

you do not得到一个错误。

您可能会忘记初始化“p”(它会崩溃)。

事实上,您不必将“p”指定为变量(就像您必须将“v”和“x”指定为变量一样)。

为什么会这样呢?

这似乎是一个大问题。

我是否需要做一些不同的事情,以使编译器强制执行“p”,就像它通常强制协议中的变量一样?


另一种看待这个问题的方式:

准确给出我上面的代码:

有办法吗强制编译器在消费者类中需要“p”的初始化程序?

例如。

我试过这个...

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

但这是行不通的。

(奇怪的是,编译 - 实际上我不知道它到底在做什么!它似乎与扩展中的 p 是“不同的”p。但无论如何,它并不强制需要初始化程序。)

简而言之,再次,我可以在上面做或添加一些东西,这将使编译器强制我初始化伪属性,就像我在协议中放置属性(例如“x”)时通常所做的那样”或“v”。

?

  • 也许我必须在协议中添加一些普通属性(如“pp”),并以某种方式使 p 与该属性相关?只是一个想法。

(脚注——见this https://stackoverflow.com/questions/41793680了解上述协议中所需的“:类”。)


回答我自己的问题:

我上面的困惑是有没有什么可初始化的. The var p:P 在扩展中(带有 get 和 set 代码块)只是两个函数。

没有什么可以初始化的。

例如:在我的额外问题中,我问“如何强制一致的类在唤醒时初始化它?”那是没有意义的。如果有的话,人们可能会问:“如何强制一致的类确保在唤醒时‘使用这些函数’?” - 这与初始化无关。

还要注意的是,我在计算变量中的特定示例代码碰巧(无关地)使用了未初始化的变量 - 导致混乱。


你不必实施p在协议的采用者中,因为协议扩展已经提供了实现。这就是协议扩展is.

更简单的例子:

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

请注意,即使 C 没有声明,(1) 也会编译greet(2) 即使 C 不包含以下实现,它也会运行greet。那是因为这是协议扩展的工作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

协议扩展似乎没有在消费者中强制执行变量? 的相关文章

随机推荐