[swift-evolution] [Proposal] Protected Access Level

Leonardo Pessoa me at lmpessoa.com
Sat May 28 18:36:24 CDT 2016

If we're to introduce the protected visibility, I think we should as well make it automatically internal or introduce an explicit protected internal visibility. I've been through many cases while programming in C# 'where' this was handy (thou I cannot name one from memory right now; it's been so many years ago...)

-----Original Message-----
From: "Xiaodi Wu via swift-evolution" <swift-evolution at swift.org>
Sent: ‎28/‎05/‎2016 08:10 PM
To: "Vanderlei Martinelli" <vmartinelli at alecrim.com>; "swift-evolution" <swift-evolution at swift.org>
Subject: Re: [swift-evolution] [Proposal] Protected Access Level

Seems entirely reasonable to me. POP aficionados may object, but I think the pros and cons of this type of access are well trodden terrain and I think it's a net win to have this available in Swift going forward.

On Sat, May 28, 2016 at 18:53 Vanderlei Martinelli via swift-evolution <swift-evolution at swift.org> wrote:


This is the first draft. I'd like to know your opinion about it.

(I know that this subject could have been discussed before. If so, please indicate me the correct thread to follow and interact.)


Vanderlei Martinelli


Protected access level will enable entities to be used within the container type and by derived types only.
Today Swift has three access levels (public, internal and private), but lacks a way to describe a member that can be only visible to its type or derived types.
A common case is the UIView from UIKit. Many developers are tempted to make this call:
view.layoutSubviews()The documentation says: "You should not call this method directly. If you want to force a layout update, call the setNeedsLayoutmethod instead to do so prior to the next drawing update. If you want to update the layout of your views immediately, call the layoutIfNeeded method."
But yes, you should call this method directly if you are subclassing the view and needs to perform additional layout to its subviews ("subclasses can override this method as needed"):
public override func layoutSubviews() {
    // We are calling the super method directly here.
    // Do more adjustments to this view's subviews...
}So, yes, we can call this method directly when subclassing, but the Swift compiler will not prevent you from do this when not subclassing or from any other foreign class. It will not even issue a warning.
In Objective-C problems like this are usually "solved" my adding a kind of "protected" header (.h) that is intended to be included only when the developer is subclassing. In Swift we do not have headers, but we have the new access level model. So, if the declaration of this method was...
protected func layoutSubviews()... no one outside the class or derived classes would be allowed to call this method directly.
Of course, there are other cases in the Cocoa frameworks and there are many other cases when we are developing software in Swift that the protected access level would be very usefull.
Proposed solution
Create the protected access level.
Detailed design
Reference Types (classes)
When declarated by a class the protected member will be visible to the class itself and all the derived classes.
// BaseClass.swift
public class BaseClass {
    public protected(set) var x = 20
    protected let y = 10
    protected func doSomething() {
        // ...

// DerivedClass.swift
public class DerivedClass: BaseClass {
    protected override doSomething() {
        self.x = 10 * self.y
}If the member is declared as final then it will be visible but not can be overrided by the derived classes. Just like it works with other access levels.
Value Types (structs, enums, etc.)
Value types cannot have derived types. In this case the protected access level does not make sense and will not be allowed in their members.
Protocols do not declare access level for their members. So the protected access level is not applicable here.
Extensions will not be able do be protected nor their members.
Special Note
The protected access level can only be applied to classes, structs and other types when nested inside other type. So the following code will not compile:
<code style="margin:0px;padding:0px;border:none;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;background-image:none;font-family:Consolas,Monaco,&#39;Andale Mono

[The entire original message is not included.]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160528/28a91b87/attachment.html>

More information about the swift-evolution mailing list