Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> iOS

Static Variable trong Swift: Khi nào và cách nào sử dụng

Static Variable (biến tĩnh): Biến thuộc về Type (Class/Struct/Enum) chứ không phải instance (object). Chỉ có một bản sao duy nhất cho toàn chương trình, được chia sẻ bởi tất cả instances.

Khái niệm cốt lõi


class Student {
    static let section: String = "A"     // Static constant (type property)
    static var day: String = "Monday"    // Static variable (type property)
    
    var name: String = "Akash"           // Instance property
    var rollNum: Int = 1                 // Instance property
}

let student1 = Student()
let student2 = Student()

// Instance properties - riêng biệt mỗi object
print(student1.name) // "Akash"
student1.name = "Aman"
print(student1.name) // "Aman"
print(student2.name) // "Akash" (không ảnh hưởng)

// Static properties - CHUNG cho tất cả
print(Student.section) // "A"
print(Student.day)     // "Monday"
Student.day = "Tuesday"
print(student1.day)    // Error: 'day' is static, access via Student.day
print(Student.day)     // "Tuesday" - thay đổi cho tất cả

Static Variable trong Swift: Khi nào và cách nào sử dụng

Cú pháp khai báo


// Class
class MyClass {
    static let constant: Type = value
    static var variable: Type = value
}

// Struct (cũng dùng static)
struct MyStruct {
    static let constant: Type = value
    static var variable: Type = value
}

// Enum
enum MyEnum {
    static let constant: Type = value
    static var variable: Type = value
}

Khi nào dùng Static Variable?

Trường hợp Ví dụ
Hằng số toàn cục cho type static let maxRetryCount = 3
Shared state / Singleton data static var currentUser: User?
Cache / Registry static var imageCache = NSCache<...>()
Configuration mặc định static var defaultTimeout: TimeInterval = 30
Counter / ID generator static var nextId = 0
Utility functions (stateless) static func formatDate(_ date: Date) -> String

Static vs Class Variable (Class chỉ)


class Parent {
    static let staticProp = "Static - không override được"
    class var classProp: String { "Class - có thể override" }
}

class Child: Parent {
    // static var staticProp = "Child" // ❌ Lỗi: Cannot override static property
    override class var classProp: String { "Child override" }
}

Static trong Struct vs Class

  • Struct: Chỉ có static (value type, không kế thừa)
  • Class: Có cả static (final) và class (overridable)
  • Protocol: Yêu cầu static cho type requirements

Global Variable vs Static Variable


// Global variable (file-level)
private let apiKey = "secret" // Chỉ truy cập trong file này

// Static variable (type-level)
struct Config {
    static let apiKey = "secret" // Truy cập: Config.apiKey
}

// Struct namespace pattern (Khuyến nghị cho constants)
struct AppConstants {
    static let apiBaseURL = "https://api.example.com"
    static let maxFileSize = 10 * 1024 * 1024
    static let defaultPageSize = 20
}

// Usage
let url = AppConstants.apiBaseURL

Memory & Lifecycle

  • Khởi tạo: Lazy - lần đầu truy cập (thread-safe từ Swift 4)
  • Hủy: Khi app terminate (không bao giờ deinit trong runtime)
  • Thread-safe cho khởi tạo, nhưng không thread-safe cho read/write nếu mutable → dùng lock/actor

Best Practices

  • Ưu tiên static let (constant) hơn static var
  • Dùng struct làm namespace cho constants (không instance, không kế thừa)
  • Tránh mutable static state (shared mutable state = bug source)
  • Nếu cần mutable shared state → dùng Actor (Swift 5.5+) hoặc DispatchQueue sync
  • Document rõ ràng: thread-safety, lifecycle, mục đích