iOS Swift No.26 - access control 2

Chapter 26 access control

3. Access Control Syntax

Before the entity introducer, we can use these five modifiers (open, public, internal, fileprivate or private) to define the five access levels of the entity.

public class SomePublicClass {}
internal class SomeInternalClass {}
fileprivate class SomeFilePrivateClass {}
private class SomePrivateClass {}

public var somePublicVariable = 0
internal let someInternalConstant = 0
fileprivate func someFilePrivateFunction() {}
private func somePrivateFunction() {}

Unless otherwise specified, the default access level of the entity is the internal access level. See the default access level for details. This means that SomeInternalClass and someInternalConstant still have implicit internal access levels without explicitly declaring access levels using modifiers:

class SomeInternalClass {}       // implicitly internal
let someInternalConstant = 0     // implicitly internal

4. Custom Type

If we want to specify an access level for a custom type, we can specify its access level when defining the type. At this time, the new type can be used anywhere allowed by its access level. For example, if we define a file private class, this class can only be used in the source file that defines it. It can be used as attribute type, function parameter type or return type, and so on.

The access control level of a type also affects the default access level of type members (properties, methods, constructors, and subscripts). If the access level of a type is defined as private or file private, the member access level of the type will also be defined as private or file private. If we define the access level of a type as internal or public (or use a default internal access level without specifying the access level), the access level of members of this type will also be internal.

public class SomePublicClass {                   // Clear access levels
    public var somePublicProperty = 0            // Clear access levels 
    var someInternalProperty = 0                 // Implied access level
    fileprivate func someFilePrivateMethod() {}   // Clear access levels 
    private func somePrivateMethod() {}          // Clear access levels 
}

class SomeInternalClass {                        // Implied access level
    var someInternalProperty = 0                 // Implied access level
    fileprivate func someFilePrivateMethod() {}   // Clear access levels 
    private func somePrivateMethod() {}          // Clear access levels 
}

fileprivate class SomeFilePrivateClass {          // Clear access levels 
    func someFilePrivateMethod() {}              // Implied access level 
    private func somePrivateMethod() {}          // Clear access levels
}

private class SomePrivateClass {                 // Clear access levels
    func somePrivateMethod() {}                  // Implied access level
}

4.1 Tuple Types

The access level of tuple type is the most restricted access level among all types used in the tuple. For example, if we combine two different types into a tuple, one is internal access and the other is private access, the access level of the tuple will be private. The level of access is also in a certain order.

4.2 Function Types

The access level of a function type is calculated as the most restricted access level by the parameter type and return type of the function. However, if this access level does not meet the default access level of the environment in which the function is defined, the access level of the function needs to be explicitly specified.

The following example defines a global function someFunction() and does not provide a specific access level modifier for the secondary function. We hope that the function has a default internal access level, but this is not the case. In fact, the writing of someFunction() code cannot be compiled successfully.

func someFunction() -> (SomeInternalClass, SomePrivateClass) {
    // function implementation goes here
}

The return type of the function is a tuple composed of two user-defined classes. One class is internal access and the other class is private access. Therefore, the overall access level of the return type is private (the private access level is the minimum access level of the tuple type)

Because the return type of the function is private, the definition of the function is valid. We want to mark the entire access level of the function with the private modifier,

private func someFunction() -> (SomeInternalClass, SomePrivateClass) {
    // function implementation goes here
}

Using the public or internal modifier to mark the definition of someFunction() or using the default internal access level is invalid, because if the access level of the function is regarded as public or internal access, we may not be able to read the private class used in the function return type. It's not valid to mark the definition of someFunction() with the public or internal modifiers, or to use the default setting of internal, because public or internal users of the function might not have appropriate access to the private class used in the function’s return type.

4.3 Enumeration Types

Each enumeration member automatically accepts the access level used by their enumeration. We cannot specify different access levels for each enumeration member. The following example enumerates CompassPoint. It has an explicit access level public, so the members of the enumeration will automatically accept the access level used by the enumeration.

public enum CompassPoint {
    case north
    case south
    case east
    case west
}

4.4 Raw Values and Associated Values

The type uses the original value or associated value of the enumeration member. The access level must be as high as that of the enumeration. For example, we can't use the access level of the original enumeration to define the value of the original member. The original value of the original enumeration member is the internal access level,

4.5 Nested Types

The access level of a nested type is consistent with that of the class it contains. Nested types defined in public types will automatically accept internal access levels. If we want the access level of the nested type in the public access level to be public, we need to define it as the public access level when defining the nested type.

Tags: Swift iOS xcode

Posted by zoobooboozoo on Thu, 19 May 2022 16:33:45 +0300