编程iOS 开发者

Swift 中 lazy 属性的关键区别是什么?何时应该使用 lazy,初始化时存在哪些特性和潜在问题?如何避免典型问题?

用 Hintsage AI 助手通过面试

回答。

Swift 中的 lazy 属性仅在首次访问时计算。这通常用于资源开销大的对象(例如,繁重的计算、网络加载),这些对象不需要立即使用。通过关键字 lazy 声明:

class DataFetcher { lazy var data: Data = self.loadData() func loadData() -> Data { /* … */ } }

特点和细节:

  • lazy 属性仅对变量 (var) 适用,而不适用于常量 (let)。
  • 在结构体内部,如果结构体是不可变的,lazy 属性不起作用。
  • 如果通过其他线程设置,则不安全。应该避免多个线程同时访问 lazy 属性。
  • 在复制类对象时,lazy 值被单独缓存为每个实例。

有陷阱的问题。

问题: "在类实例化时会为 lazy 属性创建值吗?"

回答: 不,值仅在首次访问属性时计算,而不是在实例化时。

class Expensive { init() { print("init") } } class Example { lazy var heavy = Expensive() } let foo = Example() // 什么都不输出 _ = foo.heavy // 现在输出 "init"

由于不熟悉主题细节而导致的实际错误示例。


故事

在一个双平台项目中,使用 lazy 数组(lazy var)来存储图像缓存。在多个线程同时访问时发生了竞态,包裹了 lazy var 的互斥锁——但忘记了 lazy,这导致应用崩溃。


故事

一位年轻开发者试图声明 lazy let 来缓存重计算。代码无法编译,因为 lazy 仅允许用于 var:必须重新考虑架构。


故事

开发者在初始化时,在闭包内捕获 self 声明 lazy 属性。这导致循环引用——对象即使在所有屏幕上消失后也没有被去初始化。