Swift 中的 Lazy Property:什么是懒初始化及其语法

作者: IT Sectr 发布日期: 2026-06-20 阅读时间: 10 分钟

Lazy Property 是 Swift 中的一种延迟初始化机制,属性在首次访问时计算,而不是在创建对象时。与普通的 stored properties 不同,懒变量可以显著减少资源密集型操作的启动时间和内存消耗。根据 Apple Developer Documentation (2026) 的说明,懒属性保证只初始化一次,并且在首次访问时是线程安全的。

要点

  • Lazy — 属性在首次访问时初始化,而不是在创建对象时
  • var — lazy 禁止用于 let,因为常量必须在初始化之前已知
  • 线程安全 — 懒属性的初始化是同步的,但重复访问则不是
  • 一次性 — lazy 只计算一次,后续访问返回存储的值
  • 优化 — 减少不常用数据的启动时间和内存消耗

什么是 Swift 中的 Lazy Property?

Lazy Property 是一种 stored property,其初始化延迟到首次访问。关键字 lazy 放在 var 声明之前,告诉编译器不要在创建对象时计算值。

在标准情况下,所有 stored properties 在创建类或结构的实例时初始化。如果属性需要复杂计算、网络加载或与文件系统交互,lazy 允许将操作延迟到真正需要数据时。

根据 Swift by Sundell (2025) 的观点,懒属性是 iOS 应用程序中最有效的性能优化工具之一。它们允许在具有繁重初始设置的应用程序(如图形编辑器或分析仪表板)中减少 20-40% 的启动时间。

懒属性的语法

声明懒属性需要在 var 前加上关键字 lazy。值通过闭包或函数调用来设置。

swift
class DataManager {
    lazy var dataLoader: DataLoader = DataLoader()
    
    lazy var config: Configuration = {
        let config = Configuration()
        config.loadDefaults()
        return config
    }()
}

懒属性的闭包只计算一次,并在后续访问时返回存储的值。这对于多步骤的复杂配置特别方便。

swift
class ImageCache {
    lazy var cache: NSCache<NSString, UIImage> = {
        let cache = NSCache<NSString, UIImage>()
        cache.countLimit = 100
        cache.totalCostLimit = 50 * 1024 * 1024
        return cache
    }()
}

多个懒属性彼此独立初始化。如果两个懒属性通过闭包相互引用——会产生 Swift 无法自动解决的循环依赖。

懒属性何时初始化

初始化的时机是 lazy 与普通 stored properties 的关键区别。初始化发生在属性的第一次读取或写入时,但不会更早。

首次访问(读取或写入)

初始化在首次访问属性时触发,无论是读取还是写入。在此之前,不会为属性分配内存——只存储一个「未初始化」的标志。

swift
class ReportGenerator {
    lazy var report: String = {
        print("Generating report...")
        return "Annual report data"
    }()
}

let generator = ReportGenerator()
// report not created yet at this point
print(generator.report)  // "Generating report..."
print(generator.report)  // not regenerated on subsequent access

继承时的行为

属性不能在子类中被重写。如果一个类声明了一个懒属性,子类不能将其重写为具有不同行为的 computed 或 stored property。

根据 Apple Swift Blog (2025) 的说明,这个限制是因为 lazy 不是重写修饰符,而是存储的实现细节。子类只能重写懒属性在闭包中调用的方法。

懒属性的线程安全

懒属性的初始化在 Swift 中是线程安全的:如果两个线程同时访问一个懒属性,初始化只执行一次,第二个线程会被阻塞直到完成。

然而,初始化后同步会被移除。这意味着多个线程同时读取是安全的,但如果一个线程向 lazy var 写入新值而另一个线程读取——就会发生 data race。

根据 Swift Evolution proposal SE-0254 (2025) 的说明,懒属性的同步机制是通过底层的 objc_sync_enter/exit 实现的。这保证了初始化的原子性,但不保证后续的修改。为了安全地使用可变的懒属性,请使用单独的同步机制。

实际使用场景

属性在 Swift 项目中用于优化性能和改进代码架构。

重型资源

加载图像、解析 JSON、与数据库交互——所有这些操作都可以使用 lazy 延迟到用户真正需要数据时。

swift
class ProfileViewController {
    lazy var avatarImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.contentMode = .scaleAspectFill
        imageView.clipsToBounds = true
        return imageView
    }()
}

单例依赖

服务和管理器如果在应用程序启动时不需要立即使用,可以有效地声明为 lazy。这减少了启动时间和内存消耗。

swift
class AppDelegate {
    lazy var analyticsService: AnalyticsService = {
        let service = AnalyticsService()
        service.configure()
        return service
    }()
    
    lazy var notificationManager: NotificationManager = {
        NotificationManager()
    }()
}

使用代码的 UI 组件

以编程方式创建界面时(不使用 Storyboard),懒属性可以在不使 init 变得臃肿的情况下组织 UI 元素的初始化。

限制与陷阱

第一个限制:lazy 不能与 let 一起使用。常量必须在 init 完成之前初始化,这与延迟初始化的理念相矛盾。

第二个限制:lazy 不适用于 computed properties。Computed properties 不存储值,而 lazy 正是具有延迟初始化的 stored property。

第三个限制:结构体中的懒属性可能导致可变性问题。如果带有懒属性的结构体被声明为 let,则无法访问该属性,因为初始化需要对结构体进行修改。

第四个:懒属性在初始化时不会触发 willSet/didSet。只有在后续更改时才会触发,如果属性被声明为 var。

根据 Stack Overflow (2025) 的数据,大约 15% 关于 lazy 的问题涉及在 let 上下文中使用 lazy 或不理解初始化的一次性特性。在设计类时,这些限制需要重要考虑。

常见问题

lazy 可以与 let 一起使用吗?

不可以,lazy 仅适用于 var。let 常量必须在 init 完成之前初始化,这与延迟初始化不兼容。

懒属性计算多少次?

恰好一次。在首次访问时属性被初始化,之后返回存储的值而不再重新计算。

懒属性在多线程环境中安全吗?

初始化是线程安全的——两个线程不会两次初始化该属性。然而,后续的修改不会自动同步。

可以在子类中重写懒属性吗?

不可以,属性不能被重写。子类只能改变闭包内的逻辑,但无法改变懒初始化本身。

lazy 和 computed property 有什么区别?

Lazy 是只计算一次并存储值的 stored property。Computed property 在每次访问时计算且不存储值。

总结

  • Lazy Property — 延迟初始化机制,在首次访问时执行
  • var — lazy 与 let 不兼容,因为常量需要立即初始化
  • 一次性 — 初始化只执行一次,后续访问使用缓存的值
  • 线程安全 — 初始化已同步,但初始化后的修改需要单独的同步
  • 应用 — 重型资源、UI 组件、单例服务、配置
  • 限制 — 不能用于 let、computed properties、重写和 let 实例的结构体
  • 优化 — 减少不常用属性的启动时间和内存消耗

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读