Swift Learning access Control

Source: Internet
Author: User
Tags types of functions

Access control can limit the level of access to your code in a source file or module, which means you can control which code you can access and which code you can't access. This feature allows us to hide some of the details of the implementation of the feature, and we can clearly specify which parts of the interface we provide to others are available to them, and which are not visible to them.
You can explicitly give classes, structs, enumerations, set access levels, or you can set access levels for attributes, functions, initialization methods, basic types, subscript indexes, and so on. The protocol can also be limited to a certain extent, including global constants, variables, and functions in the Protocol.
While providing different levels of access, Swift does not stipulate that we want to explicitly specify the level of access in the code at all times. In fact, if we are developing our own apps as independent developers, rather than developing some frameworks, we can completely not explicitly specify the level of access to the code.
Note: For convenience, you can set access levels in your code (attributes, basic types, functions, etc.) in the following sections we call "entities".

Modules and source files
The access control model in Swift is based on the two concepts of module and source files.
The module refers to the framework or app bundle. In Swift, you can use the Import keyword to introduce your own project.
In Swift, the framework or app bundle is handled as a module. This framework is called a module in Swift if you are trying to implement a common function, or package code into a framework to encapsulate some common methods. Whether it is introduced into an APP project or other framework, everything inside it (attributes, functions, etc.) belongs to this module.
The source file refers to Swift file in Swift, which is the document that writes the SWIFT code, which usually belongs to a module. Typically a source file contains a class, which in turn contains the types of functions, attributes, and so on.

Access level
Swift provides three different levels of access. These access levels are relative to the entities defined in the source file, and are also relative to the modules to which the source files belong.
? Public: You can access any entity in the source file in your module or app, and others can access all the entities in the source file that were introduced into the module. Typically, when an interface or framework is available to anyone, you can set it to the public level.
? Internal: You can access any entity in the source file in your module or app, but others cannot access the entity in the source file in the module. Typically, when an interface or framework is used as an internal structure, you can set it to the internal level.
? Private: An entity that can be used only in the current source file, called a private entity. Using the private level, you can use it as an implementation detail to hide certain features.
Public is the highest level of access and private is the lowest level of access.

Usage guidelines for access levels
In Swift, the access level has the following usage guidelines: Access level uniformity. For example:
? A public access-level variable that cannot be defined as a type of internal and private. Because a variable can be accessed by anyone, it is not possible to define its type, so there is an error.
? The access level of a function cannot be higher than its parameter, the access level of the return type. Because if the function is defined as public and the parameter or return type is defined as internal or private, the function can be accessed by anyone, but its arguments and return types do not, and an error can occur.

Default Access Level
All entities in the code, if you do not explicitly define their access levels, they default to the internal level. In most cases, we don't need to explicitly set an entity's access level, because most of the time we're developing an App bundle.

Access levels for single-target applications
When you write a single-target application, all the functionality of the app is for that app, and it doesn't need to be available to other apps or modules, so we don't need to explicitly set the access level, using the default access level internal. But if you want, you can also use the private level to hide the implementation details of some features.

Access level of the framework
When you develop the framework, you need to define some entities as the public level so that others can use their functionality properly after they are imported into the framework. These entities that you define as public are the API for this framework.
Note: The internal implementation details of the framework can still use the default internal level, or it can be defined as private level. Only the entity you want to use as an API defines it as the public level.

Access control syntax
Declare the access level of an entity through the modifier public, internal, private:
public class Somepublicclass {}
Internal class Someinternalclass {}
Private class Someprivateclass {}

public var somepublicvariable = 0
Internal Let Someinternalconstant = 0
Private Func Someprivatefunction () {}
Unless there is a special description, the entity uses the default access level internal, which can be viewed in the section of the default access level. This means that Someinternalclass and someinternalconstant do not explicitly use modifiers to declare access levels, but they still have an implicit access level of internal:
Class Someinternalclass {}//implicit access level internal
var someinternalconstant = 0//implicit access level internal

Custom Types
If you want to specify an explicit level of access for a custom type, then you need to be clear. That's what you want to ensure that the new type of access level matches its actual scope. For example, if the properties, functions, and return values in a class are scoped only to the current source file, then you can declare the class as private and do not need to be declared public or internal class.
The access level of a class can also affect the default access level of class members (properties, functions, initialization methods, and so on). If you declare a class as private, the default access level for all members of the class becomes private. If you declare a class as public or a internal class (or an ambiguous specified access level, and use the default internal access level), then all members of that class will have access level internal.
Note: As mentioned above, the access level for all members of a public class defaults to the internal level, not the public level. If you want to declare a member as a public level, you must explicitly declare the member with a modifier. The advantage of this is that when you define a public interface API, you can explicitly choose which properties or methods are required to be exposed, which are used internally, and avoid exposing an internally used property method to a common API error.
public class Somepublicclass {//Display public classes
public var somepublicproperty = 0//Display public class member
var someinternalproperty = 0//implicit internal class member
Private Func Someprivatemethod () {}//private class member shown
}

Class Someinternalclass {//implicit internal classes
var someinternalproperty = 0//implicit internal class member
Private Func Someprivatemethod () {}//private class member shown
}

Private class Someprivateclass {//Private classes displayed
var someprivateproperty = 0//implicit private class member
Func Someprivatemethod () {}//implicit private class member
}

Tuple type
The access level of a tuple is the most rigorous use of all types of access levels. For example, if you build a tuple that contains two different types of elements, one of which has an access level of internal and the other private level, then the access level for that tuple is private. This means that the access level of the tuple follows the lowest level of access in the tuple.
Note: Tuples differ from classes, structs, enumerations, and functions with separate definitions. The access level of a tuple is automatically deduced when it is used, rather than a definite declaration.

The access level of the

function type
function needs to be derived from the access level of the function's parameter type, the return type access level. If the access level of a function based on the parameter type and the return type does not conform to the context, then it is necessary to explicitly assert the access level of the function.
The following example defines a global function named somefunction and does not explicitly assert its access level. You might think that the function should have a default access level of internal, but that's not the case. In fact, if you do this, the compiler cannot be compiled:
func someFunction (), (Someinternalclass, Someprivateclass) {
//function Implementation goes here
}
We can see that the return type of this function is a tuple that contains two custom classes (which can be consulted for custom types). The access level of one of the classes is internal and the other is private, so the access level of the tuple is private (the access level of the tuple follows the lowest level of access in the tuple) based on the principle of the tuple access level.
because the access level of the return type of the function is private, you must explicitly apply the function using the private modifier:
private func someFunction (), Someinternalclass, Someprivateclass) {
//function implementation goes here
}
Declare the function as public or internal, or use the default access level internal is incorrect , because the return value of the private level cannot be obtained if the function is used as a public or internal level.

Enum type
The access level of a member in an enumeration inherits from the enumeration, and you cannot specify an access level for the members in the enumeration.
For example, the enumeration CompassPoint is explicitly declared as the public level, then its member North,south,east,west's access level is also public:
public enum CompassPoint {
Case North
Case South
Case East
Case West
}

Raw values and associated values
Any original value in the enumeration definition, or the associated value type must have an access level that is at least higher than the access level of the enumeration. For example, you cannot define the original value type of the private level in an enumeration of internal access levels.

Nested types
If a nested type is defined in a type of private level, the nested type automatically has the private access level. If you define a nested type in a public or internal-level type, the nested type automatically has the internal access level. If you want a nested type to have a public access level, you need an explicit access level declaration for that nested type.

Sub-class
The access level of the subclass must not be higher than the access level of the parent class. For example, the access level of the parent class is internal, and the access level of the subclass cannot be declared public.
In addition, you can override any class member (method, property, initialization method, subscript index, and so on) if the subclass is not higher than the parent class access level and follows the scope of each access level (that is, the module or source file).
If we do not have direct access to a property or function in a class, we can inherit the class, making it easier to access the class members of that class. In the following example, the access level for Class A is public, and it contains a function somemethod with the access level private. Class B Inherits Class A, and the access level is declared as internal, but in class B the method SomeMethod with access level private in Class A is overridden and re-declared as the internal level. In this way, we can access the class members of the private class in a class, and can re-assert their access levels so that others use:
public class A {
Private Func SomeMethod () {}
}

Internal class B:a {
Override internal Func SomeMethod () {}
}
As long as the subclass is not higher than the parent class access level and follows the scope of each access level (that is, the scope of private is in the same source file, the scope of internal is under the same module), we can even access the parent class member in the subclass, with the subclass member. Even if the parent class has a lower access level than the subclass member:
public class A {
Private Func SomeMethod () {}
}

Internal class B:a {
Override internal Func SomeMethod () {
Super.somemethod ()
}
}
Because the parent class A and subclass B are defined in the same source file, you can call Super.somemethod () in the overridden SomeMethod method in Class B.

constants, variables, attributes, subscripts
Constants, variables, and properties cannot have a higher level of access than their type. For example, you define a property of the public level, but its type is private, which is not allowed by the compiler. Similarly, the subscript cannot have a higher access level than the index type or return type.
If the definitions of constants, variables, attributes, and subscript indexes are of the private level, then they must explicitly declare the access level to private:
private var privateinstance = Someprivateclass ()

Getter and setter
The access levels for constants, variables, attributes, index getters, and setters are inherited from the access level of the members to which they belong.
The access level of the setter can be lower than the access level of the corresponding getter, so that you can control read and write permissions for the variable, attribute, or subscript index. Before var or subscript defines a scope, you can declare a lower access level for the Write permission of its gate by private (set) or internal (set).
Note: This rule applies to properties that are used as storage or as properties for calculations. Even if you do not explicitly declare a getter for storing properties, Setter,swift also implicitly creates getter and Setter for it, which is used to read the property. Use Private (set) and internal (set) to change the access level of the setter implicitly created by Swift. The same is true in the computed properties.
The following example defines a struct named trackedstring, which records the number of times the Value property has been modified:
struct Trackedstring {
Private (set) var numberofedits = 0
var value:string = "" {
Didset {
numberofedits++
}
}
}
The trackedstring struct defines a property that is stored with the name value, type string, and set the initialization value to "" (that is, an empty string). The struct also defines another property named Numberofedits, type int, which is used to store the number of times the property value has been modified. The implementation of this function is implemented by the Didset method of the property value, and whenever a new value is assigned to value, the Didset method is called, adding one to Numberofedits.
struct Trackedstring and its property value have no explicit declared access level, so they all have a default access level of internal. However, the Numberofedits property of the struct is declared with the private (set) modifier, which means that the Numberofedits property can only be assigned in the source file that defines the struct. The getter of the Numberofedits property is still the default access level internal, but the setter's access level is private, which means that the property is readable and writable only in the current source file, which is only a readable property in the module to which the current source file belongs.
If you instantiate the trackedstring struct and modify the value of the values property multiple times, you will see that the value of numberofedits changes with the number of changes:
var stringtoedit = trackedstring ()
Stringtoedit.value = "This string would be tracked."
Stringtoedit.value + = "This edit would increment numberofedits."
Stringtoedit.value + = "So would this one."
println ("The number of edits is (stringtoedit.numberofedits)")
Prints "The number of edits is 3"
Although you can instantiate the struct in a different source file and get the value of the Numberofedits property, you cannot assign it to a value. This will tell the user very well that you can use it without knowing its implementation details.

Initialization
We can specify the access level for a custom initialization method, but it must be below or equal to the access level of the class to which it belongs. However, if the initialization method must be used, it must have the same access level as the owning class.
As with a function or method parameter, the access level of the initialization method parameter cannot be lower than the access level of the initialization method.

Default Initialization method
Swift provides a default, parameterless initialization method for structs and classes that provides assignment operations for all their properties, but does not give a specific value. The default initialization method can be used to see default initializers. The access level of the default initialization method is the same as the access level of the owning type.
Note: If a type is declared as the public level, the default initialization method has an access level of internal. If you want the parameterless initialization method to be used in other modules, you must provide an parameterless initialization method with the public access level.

Default member initialization method for structs
If any of the storage properties in the struct have an access level of private, then its default member initialization method access level is private. However, the access level of the struct's initialization method is still internal.
If you want to use the default member initialization method for the struct in other modules, you need to provide a default member initialization method with access level public.

Agreement
If you want to explicitly declare access levels for a protocol, one thing to note is that you want to make sure that the protocol is only used in the scope of the access level you declare.
Each function that must be implemented in the Protocol has the same level of access as the protocol. This ensures that the user of the Protocol can implement the functions it provides.
Note: If you define a public access level protocol, implementing the necessary functions provided by the Protocol will also be the access level of public. This differs from other types, such as other types of public access levels, whose members have access levels of internal.

Protocol inheritance
If a new protocol is defined, and the Protocol inherits a known protocol, the new protocol has the highest access level and is the same as the access level of the inherited protocol. For example, you cannot define a public protocol to inherit a internal protocol.

Protocol consistency
Classes can use protocols that are lower than their own access level. For example, you can define a class of public class that can be used in other modules, and it can take a internal level protocol and can only be used in modules that define the protocol.
The access level of a class that employs the protocol follows its own and the lowest access level in the protocol. That is, if a class is of the public level, the protocol used is the internal level, and the access level of the class is internal when the protocol is adopted.
If you adopt a protocol, the access level of the method follows the protocol's access level after implementing the method that the protocol must have. For example, a class of public class, with the internal level of protocol, then the method of implementing the protocol is at least internal.
Note: As in swift and objective-c, agreement consistency guarantees that a class cannot use the same protocol in a different way in the same program.

Extended
You can extend the classes, structs, and enumerations as the conditions permit. Extended members should have access levels that are consistent with the original class members. For example, if you extend a public type, your new member should have the same default internal access level as the original member.
Alternatively, you can explicitly assert that the extended access level (such as using private extension) assigns a new default access level to all members within the extension. This new default access level can still be overridden by the access level specified by individual members.

Extension of the Protocol
If an extension takes a protocol, you cannot use the access level modifier for that extension to declare it. The method that implements the protocol in the extension will follow the access level of the protocol.

Generic type
The access level of a generic type or generic function follows the lowest level of access in the generic type, the function itself, and the generic type parameter.

Type aliases
Any type aliases that you define will be treated as different types, which are used for access control. The access level of a type alias can be less than or equal to this type of access level. For example, a private level type alias can be set to a public, internal, private type, but a public level type alias can only be set to a public level type. A class type that cannot be set to internal or private.
Note: This rule also applies to naming aliases for related types to satisfy protocol consistency.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Swift Learning access Control

Related Article

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.