18

How can I make protected (like in ruby) variable or function in Swift? I know Swift has only 3 levels but nonetheless is it possible?

Access Levels

Swift provides three different access levels for entities within your code. These access levels are relative to the source file in which an entity is defined, and also relative to the module that source file belongs to.

  • Public access enables entities to be used within any source file from their defining module, and also in a source file from another module that imports the defining module. You typically use public access when specifying the public interface to a framework.
  • Internal access enables entities to be used within any source file from their defining module, but not in any source file outside of that module. You typically use internal access when defining an app’s or a framework’s internal structure.
  • Private access restricts the use of an entity to its own defining source file. Use private access to hide the implementation details of a specific piece of functionality.

Public access is the highest (least restrictive) access level and private access is the lowest (or most restrictive) access level

Currently I see only one solution - write parent class with private modifier and children class in single file but it's kind of painful.

1

4 Answers 4

11

Swift prefers to not use protected. You can read the reasons here Access Control and protected

In contrast, protected conflates access with inheritance, adding an entirely new control axis to reason about. It doesn’t actually offer any real protection, since a subclass can always expose “protected” API through a new public method or property. It doesn’t offer additional optimization opportunities either, since new overrides can come from anywhere. And it’s unnecessarily restrictive — it allows subclasses, but not any of the subclass’s helpers, to access something.

Sign up to request clarification or add additional context in comments.

5 Comments

"Since a subclass can always expose “protected” API through a new public method or property." this is just a stupid rationale. Well my private method can also be exposed by some public method. Then why we have private?!
@Farid The thing is when your public member is exposing a private member, it is intentional and done in the same class/struct/actor that is holding the private member. But often times, you'd subclass a class provided in a library and end up exposing a protected member of superclass which is not intentional by author of the superclass. This is when it offers a false sense of access control.
@hxkl "The thing is when your public member is exposing a private member, it is intentional" I still do not agree. It might be unintentional too, just like we unintentionally expose protected members.
@Farid the difference is of ownership. When it is done in the same class, you own it, but when a subclass does it, it may not be owned by the superclass author and that’s the key.
@hvkale, Farid I am a bit confused with the conversation you both are having. Keyword "protected" intention is be get accessed within subclasses too. Superclass will always allow a protected method/variable for its subclasses to access and its intentional.
5

In Ruby's point of view, it may be important. However in Swift, neither it is useless, nor it is a matter of the language.

Swift language is primarily based on modules when it comes to access levels. It even has public private(set) variables, which is much needed in Objective-C (causes boilerplate).

Comments

5

There's no equivalent to protected in Swift where only subclasses have access to the method. Personally, I don't miss it.

In Swift (as Objective-C) there is far less emphasis on subclassing than other languages. If you find you have a set of methods that you want to be protected, it is probably better to factor them out as a delegate.

5 Comments

@Arsen What do you mean by "secretly"?
I would like to hear more about how to factor them out as a delegate.
@DavidRector If you have a load of protected methods that must be implemented by a subclass, put them all in a protocol and have a delegate property which is an object that implements the protocol. Then your main class calls methods on the delegate instead of the protected methods.
That's not an option. I have an NSOperation subclass and I want to expose a method to finish the operation. Only subclass should be able to call it. Doing so from the outside would cause an internal state inconsistency and potentially wreck my entire app. Delegate is not an option, protected method is. It looks like my only solution besides ignoring the problem is to pass around closures that call into private methods.
@BenAffleck NSOperation is an Objective-C class. Even private methods don't really have meaning with Objective-C classes. I think your best option is to make the method more robust so calling it from outside of the class doesn't damage the state.
-1

Swift 3.0 not cantains protected modifier. In our sdk we use internal(set) modifier that approve set operation only in sdk project.

private var _authorized : Bool = false public internal(set) var authorized : Bool { get { return _authorized; } set { _authorized = newValue } } 

2 Comments

you really could just use public internal(set) var authorized : Bool instead of splitting the two properties and have the getter and setter for the public one
How is this even related?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.