HoRain云--Swift访问控制全解析:从入门到精通
HoRain 云小助手个人主页⛺️生活的理想就是为了理想的生活!⛳️ 推荐前些天发现了一个超棒的服务器购买网站性价比超高大内存超划算忍不住分享一下给大家。点击跳转到网站。目录⛳️ 推荐1. 访问级别概览open 和 publicinternal默认级别fileprivateprivate2. 详细使用示例3. 访问级别规则基本原则具体规则示例4. 实际应用场景框架开发使用 open/publicApp 内部封装使用 internal/fileprivate/private单元测试使用 testable import5. 最佳实践1. 从最严格开始2. 框架 vs App3. 属性访问控制4. 扩展中的访问控制6. 模块化考虑模块边界依赖管理7. 迁移注意事项Swift 的访问控制Access Control用于限制代码的可见性和可访问性确保代码的封装性和安全性。Swift 提供了 5 种访问级别从最开放到最严格依次为1. 访问级别概览open和publicopen最高访问级别允许在定义模块内外访问且允许被继承和重写public允许在定义模块内外访问但不允许被继承和重写类或不允许被重写方法/属性internal默认级别允许在同一个模块内访问适用于 app 或 framework 内部代码fileprivate限制在当前源文件内访问适用于需要在文件内共享但不想暴露给其他文件的代码private限制在当前声明的封闭作用域内访问Swift 4 允许在同一个文件的扩展中访问2. 详细使用示例// 1. open 和 public open class OpenClass { open func openMethod() {} // 可被继承和重写 public func publicMethod() {} // 可访问但不可重写 } public class PublicClass { public func publicMethod() {} // 可访问但不可重写 open func openMethod() {} // 编译错误public 类不能有 open 成员 } // 2. internal默认 class InternalClass { // 默认是 internal func internalMethod() {} // 默认是 internal } // 3. fileprivate struct FilePrivateStruct { fileprivate var privateVar fileprivate } // 同一个文件中可以访问 extension FilePrivateStruct { func accessPrivateVar() { print(privateVar) // ✅ 允许访问 } } // 4. private class PrivateClass { private var secret private func useSecret() { print(secret) // ✅ 允许在类内部访问 } } // 同一个文件的扩展中可以访问Swift 4 extension PrivateClass { func anotherMethod() { print(secret) // ✅ Swift 4 允许 } }3. 访问级别规则基本原则访问级别不能高于其类型属性/方法的访问级别不能高于其所属类型元组类型元组的访问级别由其元素中最严格的访问级别决定函数类型函数的访问级别由其参数和返回类型的最严格访问级别决定具体规则示例// ✅ 正确internal 类的 public 方法 internal class MyClass { public func publicMethod() {} // 允许public 高于 internal } // ❌ 错误private 类的 internal 方法 private class PrivateClass { internal func internalMethod() {} // 编译错误 } // ✅ 正确访问级别匹配 public class PublicClass { public var publicProperty: String // 必须是 public internal var internalProperty: String // 可以是 internal private var privateProperty: String // 可以是 private init(publicProperty: String, internalProperty: String, privateProperty: String) { self.publicProperty publicProperty self.internalProperty internalProperty self.privateProperty privateProperty } }4. 实际应用场景框架开发使用open/public// MyFramework 框架 open class FrameworkBaseClass { open func overridableMethod() { // 框架提供的可重写方法 } public func finalMethod() { // 框架提供的不可重写方法 } } // 使用者代码 import MyFramework class CustomClass: FrameworkBaseClass { override func overridableMethod() { // ✅ 允许重写 open 方法 super.overridableMethod() } // ❌ 不允许重写 public 方法 // override func finalMethod() {} }App 内部封装使用internal/fileprivate/private// UserModel.swift struct UserModel { private(set) var id: String // 只读 id var name: String fileprivate var internalData: String // 仅在文件内可修改 init(id: String, name: String, internalData: String) { self.id id self.name name self.internalData internalData } } // UserViewModel.swift同一个文件 extension UserModel { func prepareForDisplay() - String { return \(name) - \(internalData) // ✅ 可以访问 fileprivate 属性 } }单元测试使用testable import// App 代码 internal class InternalService { fileprivate func testableMethod() - Bool { return true } } // 测试代码 testable import MyApp class ServiceTests: XCTestCase { func testInternalService() { let service InternalService() XCTAssertTrue(service.testableMethod()) // ✅ testable 允许访问 internal/fileprivate } }5. 最佳实践1.从最严格开始优先使用private然后根据需要逐步放宽避免过度使用public/open2.框架 vs App框架需要暴露的 API 用open/publicApp大部分代码用internal内部细节用private/fileprivate3.属性访问控制// 推荐读写控制分离 class Account { private(set) public var balance: Double // 外部只读内部可写 public private(set) var accountNumber: String // 外部只读内部可写 init(balance: Double, accountNumber: String) { self.balance balance self.accountNumber accountNumber } func deposit(amount: Double) { balance amount // ✅ 内部可以修改 } }4.扩展中的访问控制// 主类声明 public class PublicAPI { private var internalState hidden } // 同一个文件的扩展 extension PublicAPI { public func publicMethod() { print(internalState) // ✅ Swift 4 允许访问 private 成员 } } // 不同文件的扩展 // ❌ 无法访问 internalState6. 模块化考虑模块边界模块一个 app target、framework target 或 library模块间访问需要public/open级别模块内访问internal足够依赖管理// ModuleA public class SharedService { public func sharedMethod() {} } // ModuleB依赖 ModuleA import ModuleA class Consumer { func useService() { let service SharedService() service.sharedMethod() // ✅ 可以访问 public 成员 } }7. 迁移注意事项Swift 3 → Swift 4private在扩展中的行为改变访问级别升级通常安全但要注意 ABI 稳定性访问级别降级可能破坏现有代码需要谨慎通过合理使用 Swift 的访问控制你可以保护内部实现防止外部代码误用提供清晰 API明确哪些是公共接口减少耦合限制代码的依赖范围提高安全性防止敏感数据的意外暴露记住最小权限原则- 只给代码必要的访问权限这有助于构建更健壮、可维护的应用程序。❤️❤️❤️本人水平有限如有纰漏欢迎各位大佬评论批评指正如果觉得这篇文对你有帮助的话也请给个点赞、收藏下吧非常感谢! Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧