🎬 HoRain 云小助手个人主页

⛺️生活的理想,就是为了理想的生活!


⛳️ 推荐

前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。

目录

⛳️ 推荐

Swift 类(Class)

一、类的基本定义

1. 基本语法

2. 示例:定义一个简单的类

二、类的核心特性

1. 引用类型特性

2. 继承

3. 多态和类型转换

三、类的高级特性

1. 属性观察器

2. 静态成员

3. 可失败构造器

4. 必要构造器

四、内存管理 - ARC(自动引用计数)

1. 强引用

2. 弱引用和无主引用

五、类 vs 结构体

六、何时使用类

七、最佳实践

八、实际应用示例

1. MVC 架构中的模型类

2. 网络服务管理器

3. 观察者模式实现


Swift 类(Class)

Swift 类是一种引用类型的复合数据类型,用于定义具有属性、方法、构造器等的蓝图。与结构体不同,类支持继承、类型转换、析构器等面向对象特性。

一、类的基本定义

1. 基本语法

class 类名 {
    // 存储属性
    var 属性1: 类型
    let 属性2: 类型
    
    // 计算属性
    var 计算属性: 类型 {
        get {
            // 返回值
        }
        set {
            // 设置新值
        }
    }
    
    // 方法
    func 方法名(参数) -> 返回类型 {
        // 方法实现
    }
    
    // 构造器
    init(参数) {
        // 初始化代码
    }
    
    // 析构器
    deinit {
        // 清理代码
    }
}

2. 示例:定义一个简单的类

class Person {
    // 存储属性
    var name: String
    var age: Int
    let gender: String
    
    // 计算属性
    var description: String {
        return "\(name) is \(age) years old, gender: \(gender)"
    }
    
    // 构造器
    init(name: String, age: Int, gender: String) {
        self.name = name
        self.age = age
        self.gender = gender
    }
    
    // 方法
    func celebrateBirthday() {
        age += 1
        print("\(name) is now \(age) years old!")
    }
    
    // 析构器
    deinit {
        print("\(name) is being deallocated")
    }
}

二、类的核心特性

1. 引用类型特性

let person1 = Person(name: "John", age: 25, gender: "Male")
let person2 = person1 // person2 指向同一个实例

person2.name = "Jane"
print(person1.name) // 输出: Jane (person1 也被修改)
print(person1 === person2) // true,指向同一个实例

2. 继承

class Student: Person {
    var studentID: String
    var grade: String
    
    // 重写父类属性
    override var description: String {
        return super.description + ", Student ID: \(studentID), Grade: \(grade)"
    }
    
    // 便利构造器
    convenience init(name: String, age: Int, studentID: String, grade: String) {
        self.init(name: name, age: age, gender: "Unknown", studentID: studentID, grade: grade)
    }
    
    // 指定构造器
    init(name: String, age: Int, gender: String, studentID: String, grade: String) {
        self.studentID = studentID
        self.grade = grade
        super.init(name: name, age: age, gender: gender)
    }
    
    // 重写父类方法
    override func celebrateBirthday() {
        super.celebrateBirthday()
        print("\(name) got a birthday gift from school!")
    }
}

3. 多态和类型转换

class Teacher: Person {
    var subject: String
    
    init(name: String, age: Int, gender: String, subject: String) {
        self.subject = subject
        super.init(name: name, age: age, gender: gender)
    }
    
    override var description: String {
        return super.description + ", teaches \(subject)"
    }
}

// 多态示例
var people: [Person] = [
    Student(name: "Alice", age: 18, gender: "Female", studentID: "S001", grade: "A"),
    Teacher(name: "Bob", age: 35, gender: "Male", subject: "Math")
]

for person in people {
    print(person.description)
    // 根据类型进行转换
    if let student = person as? Student {
        print("Student ID: \(student.studentID)")
    } else if let teacher = person as? Teacher {
        print("Subject: \(teacher.subject)")
    }
}

三、类的高级特性

1. 属性观察器

class BankAccount {
    var balance: Double = 0.0 {
        willSet(newBalance) {
            print("Balance will change from \(balance) to \(newBalance)")
        }
        didSet {
            if balance < 0 {
                print("Warning: Negative balance!")
            }
        }
    }
    
    init(initialBalance: Double) {
        balance = initialBalance
    }
}

2. 静态成员

class MathUtils {
    static let pi = 3.14159265359
    static let e = 2.71828182846
    
    static func square(_ number: Double) -> Double {
        return number * number
    }
    
    class func cube(_ number: Double) -> Double {
        return number * number * number
    }
}

print(MathUtils.pi) // 3.14159265359
print(MathUtils.square(5)) // 25.0
print(MathUtils.cube(3)) // 27.0

3. 可失败构造器

class Product {
    let id: String
    let name: String
    let price: Double
    
    init?(id: String, name: String, price: Double) {
        guard price >= 0 else {
            return nil // 价格不能为负数
        }
        self.id = id
        self.name = name
        self.price = price
    }
}

if let product = Product(id: "P001", name: "iPhone", price: 999.99) {
    print("Product created: \(product.name)")
} else {
    print("Failed to create product")
}

4. 必要构造器

class Vehicle {
    var numberOfWheels: Int
    
    required init(numberOfWheels: Int) {
        self.numberOfWheels = numberOfWheels
    }
}

class Car: Vehicle {
    var brand: String
    
    required init(numberOfWheels: Int) {
        brand = "Unknown"
        super.init(numberOfWheels: numberOfWheels)
    }
    
    init(brand: String, numberOfWheels: Int) {
        self.brand = brand
        super.init(numberOfWheels: numberOfWheels)
    }
}

四、内存管理 - ARC(自动引用计数)

1. 强引用

class Apartment {
    let number: Int
    var tenant: Person?
    
    init(number: Int) {
        self.number = number
    }
    
    deinit {
        print("Apartment #\(number) is being deallocated")
    }
}

var john: Person? = Person(name: "John", age: 25, gender: "Male")
var apartment101: Apartment? = Apartment(number: 101)

apartment101?.tenant = john
john = nil // 不会释放,因为apartment101还持有引用

2. 弱引用和无主引用

class Customer {
    let name: String
    var apartment: Apartment?
    
    init(name: String) {
        self.name = name
    }
    
    deinit {
        print("\(name) is being deallocated")
    }
}

class ApartmentWithWeakRef {
    let number: Int
    weak var tenant: Customer? // 弱引用,不增加引用计数
    
    init(number: Int) {
        self.number = number
    }
    
    deinit {
        print("Apartment #\(number) is being deallocated")
    }
}

var alice: Customer? = Customer(name: "Alice")
var apartment202: ApartmentWithWeakRef? = ApartmentWithWeakRef(number: 202)

apartment202?.tenant = alice
alice = nil // 释放Customer,因为弱引用不阻止释放
apartment202 = nil // 释放Apartment

五、类 vs 结构体

特性 结构体
类型 引用类型 值类型
继承 支持 不支持
类型转换 支持运行时检查 不支持
析构器 支持 deinit 不支持
引用计数 有 ARC 管理
mutating 方法 不需要 mutating 需要 mutating
内存分配 堆分配 栈分配(通常)
性能 通常较慢 通常更快
共享状态 多个引用共享同一实例 每个变量有自己的拷贝

六、何时使用类

推荐使用类的场景:

  • 需要继承和多态
  • 需要引用语义(多个引用指向同一实例)
  • 需要析构器进行资源清理
  • 需要 Objective-C 互操作
  • 需要类型转换(如 as?, is
  • 处理复杂对象图,避免大量拷贝

推荐使用结构体的场景:

  • 数据相对简单且独立
  • 需要值语义(拷贝而非共享)
  • 性能敏感的场景
  • 不需要继承
  • 通常作为数据模型

七、最佳实践

  1. 优先使用值类型:除非需要类的特性,否则优先选择结构体
  2. 避免循环引用:使用 weakunowned 打破强引用循环
  3. 封装良好:使用 privatefileprivate 等访问控制修饰符
  4. 构造器设计:提供便利构造器简化初始化
  5. 协议导向:优先使用协议而非继承来共享行为
  6. 内存安全:确保无主引用始终有值,避免悬垂指针
  7. 单一职责:每个类应该只有一个职责,避免上帝对象

八、实际应用示例

1. MVC 架构中的模型类

class UserModel {
    private(set) var id: UUID
    private(set) var username: String
    private(set) var email: String
    private(set) var createdAt: Date
    
    var displayName: String {
        return username
    }
    
    init(username: String, email: String) {
        self.id = UUID()
        self.username = username
        self.email = email
        self.createdAt = Date()
    }
    
    func updateUsername(_ newUsername: String) {
        guard !newUsername.isEmpty else { return }
        username = newUsername
    }
}

2. 网络服务管理器

class NetworkManager {
    static let shared = NetworkManager()
    
    private let baseURL = "https://api.example.com"
    private let session = URLSession.shared
    
    private init() {}
    
    func fetchData<T: Decodable>(endpoint: String, completion: @escaping (Result<T, Error>) -> Void) {
        guard let url = URL(string: "\(baseURL)/\(endpoint)") else {
            completion(.failure(NSError(domain: "Invalid URL", code: 400)))
            return
        }
        
        let task = session.dataTask(with: url) { data, response, error in
            if let error = error {
                completion(.failure(error))
                return
            }
            
            guard let data = data else {
                completion(.failure(NSError(domain: "No data received", code: 404)))
                return
            }
            
            do {
                let decoder = JSONDecoder()
                let result = try decoder.decode(T.self, from: data)
                completion(.success(result))
            } catch {
                completion(.failure(error))
            }
        }
        
        task.resume()
    }
}

3. 观察者模式实现

protocol Observer {
    func update(data: Any)
}

class Subject {
    private var observers = [Observer]()
    private var state: Any?
    
    func attach(observer: Observer) {
        observers.append(observer)
    }
    
    func detach(observer: Observer) {
        observers = observers.filter { $0 !== observer }
    }
    
    func notify() {
        for observer in observers {
            observer.update(data: state ?? "")
        }
    }
    
    func setState(_ newState: Any) {
        state = newState
        notify()
    }
}

class ConcreteObserver: Observer {
    let name: String
    
    init(name: String) {
        self.name = name
    }
    
    func update(data: Any) {
        print("\(name) received update: \(data)")
    }
}

Swift 类提供了强大的面向对象编程能力,通过合理使用继承、多态、内存管理等特性,可以构建出灵活、可维护的应用程序架构。理解类的引用类型特性和适用场景,是编写高质量 Swift 代码的关键。

❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐