632  字
  3  分钟 
  Swift 访问控制 
 概念
Swift的访问控制基于 模块(Module) 和 源文件(Source File) 两个维度,定义了五个访问级别(从高到低):
- open- 允许跨模块访问,且类可被继承、方法可被重写。
- 开源框架或库的公共API设计(如 UIKit中的公开类)。
 
- public- 跨模块可见,但类不可被继承,方法不可被重写。
- 公共接口的内部实现(如库的底层逻辑)。
 
- internal(默认级别)- 仅限当前模块内访问。
- 应用或框架的内部组件交互。
 
- fileprivate- 同一源文件内可见。
- 同一文件内的多个类共享私有工具方法。
 
- private- 限定于声明的作用域(如类、结构体内部)及其扩展(若在同一文件)。
- 隐藏类内部状态或敏感数据(如银行账户的 balance属性)。
 
示例对比:
open class OpenClass {}public class PublicClass {}internal class InternalClass {}fileprivate class FilePrivateClass {}private class PrivateClass {}
// ModuleB.swift(导入ModuleA后)let obj1 = OpenClass()    // ✅let obj2 = PublicClass()  // ✅let obj3 = InternalClass()// ❌(不可见)设计原则
- 级别降序原则
 • 高访问级别实体不能包含更低级别的成员。例如,public类中的属性不能是private的。
- 函数与类型依赖
 • 函数的访问级别不能高于其参数或返回值的最高级别。
- 子类与协议限制
 • 子类访问级别不能高于父类,协议方法默认与协议同级别。
- 扩展的访问控制
 • 扩展中的成员默认继承原类型的访问级别,但可通过显式声明调整。
示例
场景1:封装敏感数据
class BankAccount {    private var balance: Double = 0.0    public func deposit(amount: Double) {        guard amount > 0 else { return }        balance += amount    }}此处,balance被标记为private,外部无法直接修改,确保数据安全性。
场景2:跨模块框架设计
// 框架模块中声明公共APIopen class NetworkManager {    open func fetchData() { /* ... */ }    public var timeout: TimeInterval = 30}
// 应用模块继承并扩展class CustomNetworkManager: NetworkManager {    override open func fetchData() { /* 自定义实现 */ }}open允许其他模块继承和重写,而public属性仅暴露接口。
最佳实践
- 优先使用最小可见权限
- 默认使用internal,仅在需要时提升级别。
 
- 默认使用
- 避免滥用open- 仅在需要跨模块继承时使用,否则用public减少API暴露风险。
 
- 仅在需要跨模块继承时使用,否则用
- 利用fileprivate共享工具代码- 在同一文件中复用私有逻辑,避免全局污染。
 
 
  