我不是罗大锤我不是罗大锤

我不是罗大锤

我不是罗大锤我不是罗大锤

我不是罗大锤

首页首页
分类分类
标签标签
友情链接友情
日记日记

在线人数:0 人

文章总浏览量:21168

Powered byNola

Swift weak & unownedSwift weak & unowned

Swift weak & unowned

&Swift#Swift

允许评论

6 个月前

在 Swift 中,weak 和 unowned 都用于打破引用循环(Retain Cycle),但是它们的使用场景和行为有所不同,下面讲解一下他们的区别及用法。

一、weak

Object 本身可以独立存在,并且一定是 Optional。

当赋值给一个被标记 weak 的变量时,它的引用计数不会改变。且当这个弱引用变量被释放时,这个变量将被自动设为 nil,这也是 weak 必须被声明为 Optional 的原因。

闭包中的循环引用:

当闭包被对象强引用,且闭包内部又捕获了对象自身时,会导致循环引用。

class NetworkManager {
  
  func handleData() {}
  
  func fetchData() {
    // 模拟异步网络请求
    DispatchQueue.main.asyncAfter(deadline: .now() + 2) { [weak self] in
      // 使用 weak 避免循环引用,self 可能为 nil
			self?.handleData()
    }
  }
}

当 NetworkManager 在异步操作完成前被释放,self 会自动变为 nil,避免导致程序崩溃。

二、unowned

Object 本身和连结对象需要同时存在,可以是 Optional。

被 unowned 标记的变量,即使它原来的引用已经被释放,它仍然会保持对被释放的对象的一个“无效”引用。如果它不是 Optional,它也不会被指向 nil。所以此时如果试图去访问该变量,程序就会崩溃。

对象间的父子关系:

当一个对象的生命周期严格依赖另一个对象时,可以使用 unowned。

class Customer {
  var creditCard: CreditCard?
}

class CreditCard {
  // 非 Optional,其生命周期与 Custmer 一致
  unowned let owner: Customer
  init(owner: Customer) {
    self.owner = owner
  }
}

var customer: Customer? = Customer()
customer!.creditCard = CreditCard(owner: customer!)

// Customer 和 CreditCard 同时释放
customer = nil

避免可选解包的麻烦:

当两个对象生命周期完全一致时,unowned 可以简化代码。

class Parent {
  var child: Child
  init() {
    child = Child(parent: self)
  }
}

class Child {
  // 非 Optional,因为 Parent 一定存在
  unowned let parent: Parent
  init(parent: Parent) {
    self.parent = parent
  }
}

var parent: Parent? = Parent()

// Parent 和 Child 同时释放
parent = nil

就算 unowned 被设为了 Optional,在存取 unowned 的时候,如果 Optional 本身已经被转换成了 case some,那它还是会继续进行存取,所以仍然可能导致程序崩溃。

三、如何选择

根据苹果的官方文档的建议,当我们知道两个对象的生命周期并不相关,那我们必须使用 weak。相反,非强引用对象拥有和强引用对象同样或者更长的生命周期的话,则应使用 unowned。

  1. 使用 weak 的场景:
    • 闭包可能被异步执行,且对象可能提前释放(如网络请求、定时器等)。
    • 引用对象可能为 nil。
  2. 使用 unowned 的场景:
    • 两个对象的生命周期严格绑定(如父子关系)。
    • 需要避免可选类型(Optional)解包,且确保引用对象不会被提前释放。
场景weakunowned
闭包中的异步操作✅安全❌可能导致程序崩溃
父子对象关系❌不必要✅简洁且安全
对象可能为 nil✅安全❌不适用
目录
一、weak
二、unowned
三、如何选择
暂无评论