Swift Advanced - 在运行时设置扩展

时间:2017-11-01 11:29:45

标签: ios swift

有没有办法在Swift的运行时设置扩展名?

我得到了一个名为" CuteProtocol"该协议的扩展名为" CuteExtension"。当我想将这个扩展添加到类时,我只需按以下步骤操作:

class CuteClass: UIViewController, CuteProtocol {

}

但是我有很多这样的课程应该实现这个协议,我不想一个一个地添加它们,我也不想创建基类。

有没有办法在运行时设置扩展协议,如下所示:

let cuteClass = CuteClass()
cuteClass. // ADD EXTENSION-PROTOCOL SOMEHOW HERE.

3 个答案:

答案 0 :(得分:2)

不,但你可以扩展例如UIViewController或其他基类

11/01/17 12:16:15] [SSH] Opening SSH connection to 192.168.226.197:22.
/var/lib/jenkins/.ssh/known_hosts [SSH] No Known Hosts file was found at /var/lib/jenkins/.ssh/known_hosts. Please ensure one is created at this path and that Jenkins can read it.
Key exchange was not finished, connection is closed.
java.io.IOException: There was a problem while connecting to 192.168.226.197:22
    at com.trilead.ssh2.Connection.connect(Connection.java:834)
    at com.trilead.ssh2.Connection.connect(Connection.java:703)
    at com.trilead.ssh2.Connection.connect(Connection.java:617)
    at hudson.plugins.sshslaves.SSHLauncher.openConnection(SSHLauncher.java:1284)
    at hudson.plugins.sshslaves.SSHLauncher$2.call(SSHLauncher.java:804)
    at hudson.plugins.sshslaves.SSHLauncher$2.call(SSHLauncher.java:793)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.IOException: Key exchange was not finished, connection is closed.
    at com.trilead.ssh2.transport.KexManager.getOrWaitForConnectionInfo(KexManager.java:95)
    at com.trilead.ssh2.transport.TransportManager.getConnectionInfo(TransportManager.java:237)
    at com.trilead.ssh2.Connection.connect(Connection.java:786)
    ... 9 more
Caused by: java.io.IOException: The server hostkey was not accepted by the verifier callback
    at com.trilead.ssh2.transport.KexManager.handleMessage(KexManager.java:548)
    at com.trilead.ssh2.transport.TransportManager.receiveLoop(TransportManager.java:790)
    at com.trilead.ssh2.transport.TransportManager$1.run(TransportManager.java:502)
    ... 1 more
[11/01/17 12:16:15] Launch failed - cleaning up connection
[11/01/17 12:16:15] [SSH] Connection closed.

答案 1 :(得分:1)

你可以自由地在 ObjC 中使用运行时修饰符,但在 Swift 中,这种有点模式并不常见。

注意: 如果您有兴趣,可以在ObjC Runtime Library找到有关此内容的更多信息。

答案 2 :(得分:0)

您无法在运行时设置扩展名,但您也不必在类定义中设置它们。你可以扩展类:

extension CuteClass: CuteProtocol {
    // your code conforming to Cute Protocol goes here.
}

更新1

或者,如果您希望将默认实施设置为CuteProtocol,您也可以自己扩展CuteProtocol

protocol CuteProtocol {
    func f1()
}

extension CuteProtocol {
    func f1() {
        // default implementation
    }
}

这样,如果想要或使用默认实现,每个类都可以更改f1实现。

您甚至可以添加条件扩展名,如:

extension CuteProtocol where Self: CuteClass {
    func f1() { }
    func f2() { }
}

所以如果你写extension CuteClass: CuteProtocol {},所有CuteClass实例和子类都可以访问方法f1f2

但请注意,扩展中添加的功能支持在protocol中定义的动态调度IFF。 在我提供的示例中,将使用动态分派调用f1,但将使用静态分派调用f2。即:如果CuteChildClass: CuteClass更改f2实施,并且您从f2变量调用CuteProtocol,则会调用您在扩展程序中提供的代码。