返回
Block 中的 Strong 和 Weak
IOS
2023-10-26 22:05:24
理解 Block
Block 是 Objective-C 中一种强大的语言特性,它允许我们创建类似于 C 函数的代码块。但是,与函数不同,block 能够访问其定义范围内的外部变量。
为了实现这种访问,block 在堆上分配了一个存储空间,其中包含对外部变量的引用。这种引用称为 strong reference ,因为它会将外部变量的引用计数增加 1。这意味着外部变量在 block 被销毁之前不会被释放。
Strong 和 Weak 引用
在 Objective-C 中,我们有两种类型的引用:strong 引用和 weak 引用。
Strong 引用
- 当一个对象拥有对另一个对象的 strong 引用时,强引用的对象的生命周期将与被引用的对象的生命周期相关联。
- ARC 下, strong 引用会自动管理引用计数。当强引用的对象销毁时,它的引用计数将递减,并且当引用计数变为 0 时,对象将被释放。
Weak 引用
- 当一个对象拥有对另一个对象的 weak 引用时,弱引用的对象的生命周期与被引用的对象的生命周期无关。
- ARC 下,weak 引用不会增加被引用的对象的引用计数。当被引用的对象被释放时,weak 引用将自动设置为 nil。
Block 中的引用
在 block 中,默认情况下使用 strong 引用来捕获外部变量。这可能会导致 retain cycles ,其中两个或多个对象相互引用,从而导致内存泄漏。
为了避免这种情况,我们可以使用 weak 引用来捕获外部变量。weak 引用不会增加被引用的对象的引用计数,因此当外部变量被释放时,weak 引用将自动设置为 nil。
使用 Weak 引用避免 Retain Cycles
考虑以下示例:
- (void)myMethod {
__weak id weakSelf = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[weakSelf doSomething];
});
}
在这个示例中,我们使用了一个 weak 引用来捕获对 self
对象的引用。这将防止保留周期,因为当 self
对象被释放时,weak 引用将自动设置为 nil。
总结
在 block 中管理引用对于避免内存泄漏和保留周期至关重要。通过理解 strong 和 weak 引用之间的差异,我们可以有效地使用 block,同时保持代码健壮性和高效性。