推荐答案
在 Swift 中,weak 和 unowned 都用于处理引用类型的弱引用,以避免循环引用。它们的主要区别在于:
weak:用于可选类型的引用,当引用的对象被释放时,weak引用会自动设置为nil。因此,使用weak时,引用必须是可选的(Optional)。unowned:用于非可选类型的引用,假设引用的对象在引用期间不会被释放。如果引用的对象被释放,继续访问unowned引用会导致运行时崩溃。
本题详细解读
weak 关键字
特点:
weak引用必须是可选的,因为当引用的对象被释放时,weak引用会自动设置为nil。- 使用
weak可以避免循环引用,特别是在闭包中捕获self时。
适用场景:
- 当两个对象之间存在循环引用,且其中一个对象的生命周期可能比另一个短时,使用
weak是安全的。
- 当两个对象之间存在循环引用,且其中一个对象的生命周期可能比另一个短时,使用
示例:
// www.javascriptcn.com code example class Person { var name: String weak var apartment: Apartment? init(name: String) { self.name = name } } class Apartment { var unit: String var tenant: Person? init(unit: String) { self.unit = unit } }
unowned 关键字
特点:
unowned引用是非可选的,它假设引用的对象在引用期间不会被释放。- 如果引用的对象被释放,继续访问
unowned引用会导致运行时崩溃。
适用场景:
- 当两个对象之间存在循环引用,且其中一个对象的生命周期与另一个对象相同或更长时,可以使用
unowned。
- 当两个对象之间存在循环引用,且其中一个对象的生命周期与另一个对象相同或更长时,可以使用
示例:
// www.javascriptcn.com code example class Customer { var name: String var card: CreditCard? init(name: String) { self.name = name } } class CreditCard { let number: UInt64 unowned let customer: Customer init(number: UInt64, customer: Customer) { self.number = number self.customer = customer } }
总结
- 使用
weak时,引用会自动置为nil,避免野指针问题。 - 使用
unowned时,引用不会自动置为nil,但需要确保引用的对象在引用期间不会被释放,否则会导致崩溃。