闭包捕获列表与 [weak self]
使用捕获列表,防止闭包强引用对象。
闭包捕获列表与 [weak self] 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。
欢迎
闭包会捕获其周围作用域中的变量。捕获列表(`[weak self]`、`[unowned self]`、`[value]`)可以精确控制捕获的方式。
默认的强捕获
```swift
var name = "Alice"
let greet = { print("Hello, \(name)") }
name = "Bob"
greet() // "Hello, Bob" — closure sees current value
```
默认情况下,闭包捕获的是变量的*引用*。
捕获列表基础
```swift
var count = 10
let snapshot = { [count] in print(count) } // captures value
count = 99
snapshot() // 10 — snapshot of count at capture time
```
在 `[]` 中列出值类型,会在闭包创建时复制该值。
`[weak self]` 模式
```swift
class API {
func fetch(completion: @escaping () -> Void) { ... }
}
class VC {
func load() {
api.fetch { [weak self] in
guard let self else { return } // self might be nil by now
self.updateUI()
}
}
}
```
使用 `guard let self` 延长生命周期
Swift 5.3 及更高版本:可以在守卫语句中重新绑定 `self`,而无需创建遮蔽声明:
```swift
{ [weak self] in
guard let self else { return }
// 'self' is now strong within this block
doA()
doB()
doC()
}
```
何时可以安全地使用 `[unowned self]`
```swift
button.addTarget(self, action: #selector(tap), for: .touchUpInside)
// If the button's closure is guaranteed not to outlive self:
let action: () -> Void = { [unowned self] in self.handleTap() }
```
捕获多个值
```swift
let base = 100
let multiplier = 2
let compute = { [base, multiplier] in base * multiplier }
print(compute()) // 200
```
在同一个列表中捕获多个值,并使用逗号分隔。
带命名绑定的捕获列表
```swift
let myService = service // rename in capture list:
let handler = { [service = myService] in
service.process()
}
```
这对于使用新名称捕获特定快照很有帮助。
逃逸与非逃逸
• `@escaping` 闭包可以在函数返回后存储并调用 → 存在形成循环的风险
• 非逃逸闭包会在函数返回前调用 → 不存在循环风险
```swift
func apply(_ f: () -> Void) { f() } // non-escaping, no [weak] needed
func later(_ f: @escaping () -> Void) { queue.async { f() } } // escaping
```
调试捕获问题
如果您怀疑存在循环:
1. 将 `deinit { print("deallocated") }` 添加到类中
2. 离开当前页面,或将实例设置为 nil
3. 如果没有打印 deinit 的信息 → 说明存在循环
然后将 `[weak self]` 添加到该类中的闭包里。
快速检查
捕获列表中的 `[weak self]` 有什么作用?
回顾
要点:
• 闭包默认捕获引用
• 捕获列表 `[value]` 会在创建时复制值类型
• `[weak self]`——不持有对象,自动变为 nil,并使用 `guard let self`
• `[unowned self]`——不持有对象,无法安全处理 nil
• `@escaping` 闭包需要捕获列表;非逃逸闭包通常不需要
课程完成!下一步:Swift 中的函数式编程。
常见问题解答
「闭包捕获列表与 [weak self]」课时是免费的吗?
是的 — 「闭包捕获列表与 [weak self]」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。
「闭包捕获列表与 [weak self]」这节课中我会学到什么?
使用捕获列表,防止闭包强引用对象。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Swift Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「闭包捕获列表与 [weak self]」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Swift Academy 课中编写并运行代码吗?
能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- ARC 如何计算引用
- 保留环:成因与检测
- weak 与 unowned 引用
- 闭包捕获列表与 [weak self]