Access control is used to define accessibility of a class or data members and functions of a class. We can set scope of a member so that it is visible only in the class in which it is defined or in subclasses or in the module or everywhere.
Swift provides following 5 access levels to help us with this : open, public, internal, private, fileprivate
Below is a little explanation of them (Here entity will refer to class or variable or constant or function)
- Entity with open access can be used in any source file within the module in which it is defined and also in source file from another module which imports the defining module. A class with open access can also be subclassed in the defining module or in any other module which imports the defining module. Similarly a class member(variable, function, constant) can be overridden by subclasses within the defining module or any other module that imports the defining module.
- Public access is similar to open access if we are using the entity, i.e., entity with public access can be used in any source file within the defining module or in any other module that imports the defining module. But if we talk about subclassing, public classes can only be subclassed within the defining module but not in any other module; and class members with public access can only be overridden within the defining module and not in any other module.
- Internal access is the default access level. An entity with internal access can be used and subclassed/overridden within the defining module but not in other modules.
- Private entity can only be used within the enclosing declaration like a variable will only be visible within its defining class and not anywhere else.
- File-private entity can be used within the defining source file. So a file private variable will also be available to an extension of the defining class if the extension is in the same file.
Following code snippet shows difference between private and file-private:
class AccessTest {
private var privateVar = "private"
fileprivate var fileprivateVar = "fileprivate"
func printVar() {
print(fileprivateVar)
print(privateVar)
}
}
extension AccessTest {
func printVarExt() {
print(fileprivateVar)
print(privateVar) // error => 'privateVar' is inaccessible due to 'private' protection level
}
}
// ********Another File******** //
extension AccessTest {
func printVarExtNewFile() {
print(fileprivateVar) // error => 'fileprivateVar' is inaccessible due to 'fileprivate' protection level
print(privateVar) // error => 'privateVar' is inaccessible due to 'private' protection level
}
}
For detailed explanation you can refer to apple documentation
0 Comment(s)