In Objective-C instance data can be public
, protected
or private
. For example:
@interface Foo : NSObject
{
@public
int x;
@protected:
int y;
@private:
int z;
}
-(int) apple;
-(int) pear;
-(int) banana;
@end
I haven't found any mention of access modifiers in the Swift reference. Is it possible to limit the visibility of data in Swift?
The language grammar does not have the keywords 'public', 'private' or 'protected'. This would suggest everything is public. Of course, there could be some alternative method of specifying access modifiers without those keywords but I couldn't find it in the language reference.
When one talks about making a "private method" in Swift or ObjC (or ruby or java or…) those methods aren't really private. There's no actual access control around them. Any language that offers even a little introspection lets developers get to those values from outside the class if they really want to.
So what we're really talking about here is a way to define a public-facing interface that merely presents the functionality we want it to, and "hides" the rest that we consider "private".
The Swift mechanism for declaring interfaces is the
protocol
, and it can be used for this purpose.Remember, protocols are first-class types and can be used anyplace a type can. And, when used this way, they only expose their own interfaces, not those of the implementing type.
Thus, as long as you use
MyClass
instead ofMyClassImplementation
in your parameter types, etc. it should all just work:There are some cases of direct assignment where you have to be explicit with type instead of relying on Swift to infer it, but that hardly seems a deal breaker:
Using protocols this way is semantic, reasonably concise, and to my eyes looks a lot like the Class Extentions we've been using for this purpose in ObjC.
Hopefully to save some time for those who want something akin to protected methods:
As per other answers, swift now provides the 'private' modifier - which is defined file-wise rather than class-wise such as those in Java or C# for instance. This means that if you want protected methods, you can do it with swift private methods if they are in the same file
e.g. File 1:
File 2:
}
In Beta 6, the documentation states that there are three different access modifiers:
And these three apply to Classes, Protocols, functions and properties.
For more, check Access Control.
Now in beta 4, they've added access modifiers to Swift.
from Xcode 6 beta 4 realese notes:
Access control mechanisms as introduced in Xcode 6:
Default accecss it internal, and does as such not need to be specified. Also note that the private specifier does not work on the class level, but on the source file level. This means that to get parts of a class really private you need to separate into a file of its own. This also introduces some interesting cases with regards to unit testing...
Another point to me made, which is commented upon in the link above, is that you can't 'upgrade' the access level. If you subclass something, you can restrict it more, but not the other way around.
This last bit also affects functions, tuples and surely other stuff in the way that if i.e. a function uses a private class, then it's not valid to have the function internal or public, as they might not have access to the private class. This results in a compiler warning, and you need to redeclare the function as a private function.