ios – 无法覆盖另一个模块swift中类扩展中声明的open方法

前端之家收集整理的这篇文章主要介绍了ios – 无法覆盖另一个模块swift中类扩展中声明的open方法前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在另一个模块(使用pod)中声明了类扩展.
public extension UIView {
  open func doStuff() {...}
}

当我尝试在当前项目模块中的子类中重写此方法

class ConcreteView : UIView {
  override open func doStuff() {...}
}

我收到一个错误

Overriding non-open instance method outside of its defining module

尽管该方法实际上标记为开放

作为一种解决方法,我在同一模块中声明了另一个类,其中声明了扩展并在那里覆盖了所需的方法

public class CustomView: UIView {
  override open func doStuff() {...}
}

并在主模块中将此类设置为我的类的超类

class ConcreteView : CustomView

所以只有在此之后我才能覆盖该方法.

它看起来真的像swift3中的一个错误,但也许我已经省略了为什么它以这种方式工作的一些理解?

解决方法

简答:doStuff方法
public extension UIView {
  open func doStuff() {...}
}

有一个有效的访问级别“公共”,因为扩展名是
公开的.因此,它不能在子类中重写.

请注意,Xcode警告

warning: declaring instance method in PUBLIC extension

并且警告文本应该是(见下文)

warning: declaring OPEN instance method in PUBLIC extension

解决此问题,请删除扩展的公共访问修饰符:

extension UIView {
  open func doStuff() {...}
}

现在扩展的访问级别为“open”(继承自开放类UIView)
并且doStuff的有效访问级别是“开放的”,它可以是子类.

更长的回答:

Access Control在Swift参考中
说明

… you can mark an extension with an explicit access-level modifier … to set a new
default access level for all members defined within the extension. This new default
can still be overridden within the extension for individual type members.

但实际上您只能将扩展中的类型成员限制为相同
或较低的访问权限.不幸的是,我找不到明确的参考
事实上在文档中.

SE-0117 Allow distinguishing between public access and public overridability
说明

For example,the true access level of a type member is computed as the minimum of the
true access level of the type and the declared access level of the member. If the class
is public but the member is open,the true access level is public.

但没有解释这如何适用于扩展.

检查可以在编译器源代码中看到
TypeCheckAttr.cpp.
如果项目的访问级别大于包含的访问级别
延伸然后
diag::access_control_ext_member_more
发出诊断消息:

WARNING(access_control_ext_member_more,none,"declaring %select{PRIVATE|a fileprivate|an internal|a public}0 %1 in "
    "%select{a private|a fileprivate|an internal|PUBLIC}2 extension",(Accessibility,DescriptiveDeclKind,Accessibility))

请注意,选择中缺少“打开”级别,这就是它缺失的原因

warning: declaring instance method in PUBLIC extension

猜你在找的iOS相关文章