美文网首页Swift
Swift - Access Control

Swift - Access Control

作者: ienos | 来源:发表于2019-04-11 18:05 被阅读0次

    访问控制模型是基于 Modules & Source Files
    作用:隐藏代码的实现,指定接口能够被访问和使用

    Module

    • 是单一的代码分配单元 - 一个框架或应用程序会作为独立的单元构建和发布并且可以使用 Swift 的 import 关键字导入到另一个 module
    • Swift 的 module 相当于每一个 Target (app bundle OR framework)

    Source File

    • 在一个 module 中的一个 Swift 源代码文件
    • 通常每一个类型分配在单独源文件,一个源文件也可以包括定义多个类型、方法等等

    五种访问等级

    从高到低:open / public / internal / fileprivate / private

    Open & Public

    • 在被定义的 module 中使用
    • 在其他 module 中使用,imports 被定义的 module
    • 指定 Framework 公共接口,使用 open 和 public 修饰

    Internal

    • 在被定义的 module 中使用
    • 在 app 或 Framework 内部结构时使用

    File-private

    • 在被定义的源文件中使用

    Private

    • 定义的范围内 + 同文件内的 extension 中使用

    Open 只能用于类和类成员,以下几点不同于 Public

    • < Public(类),只能在所在的 module 被子类化
    • < Public(类成员),只能在所在的 module 被子类重写
    • Open(类)能够在所在的 module 中被子类化,或者在任何已 import module 的 module 中被子类化
    • Open(类成员)能够在所在的 module 中被子类化,或者在任何已 import module 的 module 中被子类重写

    ✨访问权限的原则

    实体不能被另外一个低访问权限的实体定义
    eg:

    • 一个 public 变量不能被定义有一个 internal / file-private / private 类型定义,因为类型也许不能在 public 变量使用时有效
    • 方法 level !> 参数 level & return level

    默认访问等级 - internal

    Unit Test Targets

    除了标记 Open 和 Public,能够访问任何 internal 实体的方式:在 import module 前加 @testable

    Frameworks

    open / public 修饰 API

    自定义类型

    • 如果定义类型为 private / file-private,默认成员的访问等级也是 private / file-private
    • 如果定义类型为 internal / public,默认成员的访问等级是 Internal(如果需要,用 public 修饰,提供选择性发布,避免将内部类型作为 API)
    fileprivate class SomeFilePrivateClass {
        func someFilePrivateMethod() {}
        private func somePrivateMethod() {} 
    }
    

    元祖类型

    整个元祖类型的访问权限,决定于元祖中所有类型的最低访问权限,不能特指访问权限

    方法类型

    方法类型的访问权限,决定于方法参数类型和返回值类型的最低访问权限

    func someFunction() -> (SomeInternalClass, SomePrivateClass) {
        // function implementation goes here
    }
    // 也许会期望方法的默认访问权限为 internal,但是实际上取决于元祖类型 
    // 并且在这里不能用 public 和 internal 修饰改方法
    

    枚举类型

    • 不能为独立的枚举 case 指定不同的访问权限
    • 独立的枚举 case 自动为枚举类型的相同访问权限
    • 原生值 和 关联值 必须至少和枚举有相同的访问等级

    嵌套类型

    • 嵌套类型在一个 private 有一个自动 private 访问类型
    • 嵌套类型在一个 file-private 类型中自动有 file-private 访问类型
    • 嵌套类型在在一个 public OR internal 类型中自动有 internal 中
    • 如果需要 public 类型就显式指定

    子类化

    • 一个子类不能有高于父类的访问权限
    • 重写可以让继承的类成员比其父类更容易访问
    public class A {
        fileprivate func someMethod() {}
    }
    
    internal class B: A {
        override internal func someMethod(){
          super.someMethod()
      }
    }
    
    

    常量、变量、属性和下标

    • 不能比它的类型还高级
    • 下标不能比它的索引类型和返回值更高级
    private var privateInstance = SomePrivateClass()
    

    Setter and Getter

    • setter / getter 自动接收 常量、变量、属性、下标的访问等级
    • fileprivate(set) / private(set) / internal(set) 修饰变量 OR 下标,这个规则应用于存储属性和计算属性
    struct TrackedString {
    // setter: private ; getter: internal
        private(set) var numberOfEdits = 0
        var value: String = "" {
              didSet {
                  numberOfEdit += 1
              }
        }
    }
    
    public struct TrackedString {
        // 默认是 getter internal;此时设置为 getter public
        public private(set) var numberOfEdits = 0
        public var value: String = "" {
              didSet {
                    numberOfEdits += 1
              }
        }
        public init() {}
    }
    

    初始化

    • 自定义初始化器能够被定义低于或等于他们的类型
    • 除了 Required 初始化器必须和类有相同的访问等级
    • 初始化器的参数不能低于初始化器的本身访问等级

    默认初始化器

    • Swift 自动提供一个没有任何参数的默认初始化,为结构体和类的所有属性提供默认值,但没有提供初始化本身的方法
    • 默认的初始化器有和类型相同的访问等级,除了public 的类型

    结构体类型的默认 Memberwise 初始化器

    • 如果结构体的所有存储属性是 private, 结构体类型也是 private
    • 如果结构体的所有存储属性时 file-private,结构体类型也是 file-private
    • 如果需要 public 结构体类型能够在另外的 module 中使用,必须提供一个 public memberwise 初始化器

    协议

    -requirement 自动设置与协议相同的访问等级,并且不能设置与其不同的等级,以确保所有 requirement 能够有效适用任何遵循该协议的类型

    协议继承

    最高访问权限为父协议的等级

    协议遵循

    • 一个类型能够遵循一个低于它访问等级的协议
    • 一个类型遵循一个协议,访问等级为协议和类型的最低访问等级
    • 一个类型遵循一个协议必须确保每一个 requirement 至少有和协议相同的访问等级

    遵循协议是全局的:一个类型不能以两种不同的方式遵循一个协议

    Extensions

    class / structure / enumeration

    • 新扩展的类成员和被扩展类型的访问等级一致
      extension public / internal -> type member internal
      extension private -> type member private
      extension file-private -> type member file-private

    • 可以为所有在 extension 的成员定义一个新的等级,同样也可以针对单个成员重写
      eg: private extension

    • 如果使用了 extension 添加协议遵循,不能提供一个显式的访问等级修饰一个扩展

    在 Extension 中的私有成员

    • 声明一个私有成员在初始声明中,能在同个文件的 extension 中访问
    • 在 extension 中声明私有成员,其他来自同一文件的其他 extension 中访问
    • 在 extension 中声明私有成员,能够被来自同个文件的初始声明中访问

    泛型

    泛型类型 / 泛型方法 level = minimum (泛型类型 / 泛型方法,类型参数上的类型约束)

    类型别名

    类型别名 level <= 类型 level

    相关文章

      网友评论

        本文标题:Swift - Access Control

        本文链接:https://www.haomeiwen.com/subject/colzmqtx.html