Swift-static和class

在 Swift 中,staticclass 都用于修饰类型属性,但它们有重要的区别。让我详细解释:

基本定义

static - 静态属性

swift

复制代码
class MyClass {
    static let staticProperty = "我是静态属性"
    static var staticVariable = "我也是静态属性"
}

class - 类属性(仅用于类)

swift

复制代码
class MyClass {
    class var classProperty: String {
        return "我是类属性"
    }
}

主要区别

1. 继承行为不同

static - 不能重写

swift

复制代码
class Parent {
    static let version = "1.0"
    static var name: String { return "Parent" }
}

class Child: Parent {
    // ❌ 编译错误:不能重写静态属性
    // override static let version = "2.0"
    
    // ❌ 编译错误:不能重写静态计算属性  
    // override static var name: String { return "Child" }
}
class - 可以重写

swift

复制代码
class Parent {
    class var version: String { return "1.0" }
    class var name: String { return "Parent" }
}

class Child: Parent {
    // ✅ 可以重写类属性
    override class var version: String { return "2.0" }
    override class var name: String { return "Child" }
}

2. 存储属性 vs 计算属性

static - 支持存储属性和计算属性

swift

复制代码
class MyClass {
    // ✅ 存储属性
    static let constant = "常量"
    static var variable = "变量"
    
    // ✅ 计算属性
    static var computedProperty: String {
        return "计算属性"
    }
}
class - 只支持计算属性

swift

复制代码
class MyClass {
    // ❌ 编译错误:class 不能用于存储属性
    // class let constant = "常量"
    // class var variable = "变量"
    
    // ✅ 只能用于计算属性
    class var computedProperty: String {
        return "类计算属性"
    }
}

实际使用示例

单例模式中的使用

swift

复制代码
class NetworkManager {
    // static 用于存储单例实例
    static let shared = NetworkManager()
    
    // class 用于提供类型信息(如果需要重写)
    class var baseURL: String {
        return "https://api.example.com"
    }
    
    private init() {}
}

class TestNetworkManager: NetworkManager {
    // ✅ 可以重写类属性
    override class var baseURL: String {
        return "https://test-api.example.com"
    }
    
    // ❌ 不能重写静态属性
    // override static let shared = TestNetworkManager()
}

配置信息示例

swift

复制代码
class AppConfig {
    // 静态存储属性 - 不会改变的基础配置
    static let appName = "MyApp"
    static let buildNumber = "1.0.0"
    
    // 类计算属性 - 可能被子类重写的配置
    class var apiBaseURL: String {
        return "https://production.api.com"
    }
    
    class var isDebugMode: Bool {
        #if DEBUG
        return true
        #else
        return false
        #endif
    }
}

class TestAppConfig: AppConfig {
    // ✅ 重写环境相关的配置
    override class var apiBaseURL: String {
        return "https://test.api.com"
    }
}

在结构体和枚举中的表现

static - 适用于所有类型

swift

复制代码
struct MathUtils {
    static let pi = 3.14159
    static var calculationCount = 0
}

enum NetworkError: String {
    static let defaultMessage = "网络错误"
    case timeout = "请求超时"
    case serverError = "服务器错误"
}

class - 仅适用于类

swift

复制代码
// ❌ 在结构体和枚举中不能使用 class
struct MathUtils {
    // class var test: String { return "test" } // 编译错误
}

enum NetworkError {
    // class var test: String { return "test" } // 编译错误
}

协议中的使用

static - 在协议中定义类型属性要求

swift

复制代码
protocol Configurable {
    static var configKey: String { get }
    static func setup()
}

class MyClass: Configurable {
    // 实现协议要求
    static var configKey: String = "MyClassConfig"
    
    static func setup() {
        print("初始化设置")
    }
}

内存和行为特性

两者共同点:

  • ✅ 都是类型属性,属于类型本身而不是实例

  • ✅ 在程序运行期间只有一份内存

  • ✅ 通过类型名访问:MyClass.staticProperty

  • ✅ 线程安全的懒加载

选择指南

使用 static 当:

swift

复制代码
// 1. 需要存储属性
static let databasePath = "/data/db"

// 2. 不需要子类重写
static let appVersion = "1.0.0"

// 3. 在结构体或枚举中
static let defaultSize = CGSize(width: 100, height: 100)

// 4. 单例模式
static let shared = MyManager()

使用 class 当:

swift

复制代码
// 1. 需要子类重写行为
class var shouldLog: Bool { 
    return true 
}

// 2. 基于类型提供不同值
class var supportedFileTypes: [String] { 
    return ["json", "xml"] 
}

// 3. 多态行为
class var maximumConnections: Int { 
    return 5 
}

总结对比表

特性 static class
存储属性 ✅ 支持 ❌ 不支持
计算属性 ✅ 支持 ✅ 支持
可重写性 ❌ 不可重写 ✅ 可重写
适用类型 类、结构体、枚举 仅类
内存特性 全局唯一 全局唯一
访问方式 Type.property Type.property

理解这个区别对于设计良好的 Swift 代码架构非常重要!

相关推荐
代码or搬砖11 小时前
MyBatisPlus讲解(二)
java·mybatis
lcu11111 小时前
Java 学习42:抽象
java
Mr.朱鹏11 小时前
RocketMQ安装与部署指南
java·数据库·spring·oracle·maven·rocketmq·seata
雨中飘荡的记忆11 小时前
Spring表达式详解:SpEL从入门到实战
java·spring
Coder-coco11 小时前
个人健康管理|基于springboot+vue+个人健康管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·mysql·论文
_星辰大海乀11 小时前
IP 协议
服务器·网络·tcp/ip·nat·子网掩码·ip协议
5***262212 小时前
Spring Boot问题总结
java·spring boot·后端
xkroy12 小时前
Spring Boot日志
java·spring boot·后端
屿行屿行12 小时前
【Linux】Socket编程(基于实际工程分析)
linux·服务器·网络
n***F87512 小时前
【Spring Boot】SpringBoot自动装配-Import
java·spring boot·后端