Krótka odpowiedź:doStuff
metoda
public extension UIView {
open func doStuff() {...}
}
posiada efektywny poziom dostępu „publiczny”, ponieważ rozszerzenie jest oznaczone publicznego. Dlatego nie można go przesłonić w podklasie.
Zauważ, że Xcode ostrzega
warning: declaring instance method in PUBLIC extension
i tekst ostrzegawczy powinny być (patrz niżej)
warning: declaring OPEN instance method in PUBLIC extension
Aby rozwiązać ten problem, należy usunąć modyfikator public
dostępu rozszerzenia:
extension UIView {
open func doStuff() {...}
}
Teraz exte nsion ma poziom dostępu "otwarty" (odziedziczony po open class UIView
) , a efektywny poziom dostępu doStuff
jest "otwarty" i może być podklasowany.
Dłuższa odpowiedź:
Access Control w Swift odniesienia stwierdza, że
... 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.
ale faktycznie można ograniczyć tylko członków typu w rozszerzeniu do tego samego lub niższy dostępu. Niestety, nie znalazłem jednoznacznego odniesienia do tego faktu w dokumentacji.
SE-0117 Allow distinguishing between public access and public overridability stwierdza, że
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.
ale nie wyjaśnia, w jaki sposób odnosi się to do rozszerzenia.
Czek można zobaczyć w kodzie źródłowym kompilatora TypeCheckAttr.cpp. Jeśli poziom dostępu elementu jest większy niż poziom dostępu zawierającego przedłużenie wówczas komunikat diagnostyczny diag::access_control_ext_member_more
emitowanego:
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))
Należy zauważyć, że poziom „otwarty” brakuje w wyborze i dlatego brakuje w
warning: declaring instance method in PUBLIC extension
to wygląda podobnie: http://stackoverflow.com/questions/39141975/swift-open-keyword-overridable-method-properties-in-extension. - Usuń 'public' z' publicznego rozszerzenia UIView'. –
@MartinR yeap, działa - dzięki! Byłoby wspaniale, gdybyś sformułował opis, dlaczego działa w ten sposób w odpowiedzi, abym mógł go oznaczyć lub przynajmniej wytłumaczyć gdzieś w sieci. –