一种书呆子的问题.我不清楚,这段代码的确切作用是什么:
class Shape { }
extension Shape {
@objc func redraw() {
print("from ext")
}
}
class Circle: Shape { }
class Line: Shape {
override func redraw() { // Compiler error: Declarations from extensions cannot be overridden yet
print("from subclass")
}
}
let line = Line()
let shape:Shape = line
let circle = Circle()
line.redraw() //from subclass
circle.redraw() //from ext
shape.redraw() //from subclass
Run Code Online (Sandbox Code Playgroud)
如果我@objc在扩展中省略了关键字,代码将无法编译 - 这是预期的行为,因为扩展中的方法使用静态方法dispatch - >无法覆盖.但为什么添加@objc使它工作?根据文档和大多数文章,所有正在@objc做的是使Objective-c运行时可见.要更改方法分派类型,有一个特殊的关键字 - dynamic.但似乎这里没有必要!
帮助我弄清楚,为什么添加@objc(和省略dynamic)使这些事情成为可能.
扩展,
\n\n\n\n\n顾名思义,应该将方法扩展/添加/包含到现有的实现中,使它们成为 Objective-C 最美丽的东西之一,现在是 Swift,因为您可以将代码添加到您不拥有的类或框架。因此,从概念上来说,\n 你\xe2\x80\x99 不应该\xe2\x80\x9c 替换\xe2\x80\x9d 代码是有道理的。
\n
这就是为什么当你尝试这样做时编译器会抱怨的原因。
\n\n另请查看此答案。
\n\n然而这似乎也是一个支持问题,因为 swift 编译器只是抛出这个错误:
\n\n\n\n\n不支持覆盖扩展中的非 @objc 声明。
\n
据苹果公司称,
\n\n\n\n\n扩展可以向类型添加新功能,但不能覆盖现有功能。
\n
但事实并非如此,因为我们是从扩展覆盖的,反之亦然,\n这让我们回到了 的声明extension。
\n\n\n扩展向现有的类、结构、枚举或协议类型添加新功能。这包括扩展您无权访问原始源代码的类型的能力(称为追溯建模)。扩展类似于 Objective-C 中的类别。(与 Objective-C 类别不同,Swift 扩展没有名称。)这里.
\n
回到遗留主题swift 编译器与 Objc 编译器,
\n\n动态调度与静态调度。
\n\n苹果没有官方文档说明为什么 swift 编译器不支持此功能,或者他们是否有任何未来计划来解决此问题或将其视为一个问题。
\n\n\n\n\n然而,\xe2\x80\x99s 没有 Swift 动态调度这样的东西;我们只有 Objective-C 运行时 xe2x80x99s 动态调度。这意味着您不能\xe2\x80\x99\n 只是动态的,并且必须编写@objc 动态。因此,这实际上与之前的情况相同,只是明确了而已。
\n
这是一篇很棒的文章深入讨论了这个话题。
\n| 归档时间: |
|
| 查看次数: |
121 次 |
| 最近记录: |