ios - ARC __block 和 __weak

标签 ios objective-c automatic-ref-counting

假设我正在尝试从一个 block 中访问 self:

[someObject successBlock:^(NSArray *result) {
    [self someSuccessMethod];
} failure:^(NSString *errorMessage, int status) {
    [self someFailureMethod];
}];

我知道这会创建一个保留周期,并且 someObjectself 永远不会被取消分配。

令我困惑的是使用/不使用 __block 关键字时实际发生的情况。我可以通过对 self 进行 __weak 引用来修复保留周期:

__weak MyClass* me = self;
[someObject successBlock:^(NSArray *result) {
    [me someSuccessMethod];
} failure:^(NSString *errorMessage, int status) {
    [me someFailureMethod];
}];

我不需要在这里使用 __block,因为我不想在 block 中修改 me。据我了解,如果我不使用 __block,则会在 block 内引用 me 的副本。我的问题是:如果 block 内引用的只是对象的副本,为什么原始代码块会创建保留周期?我猜对 self 的引用只是一个副本,因为我从不使用 __block 关键字。我是不是想错了?

最佳答案

在第一种情况下, block 捕获 self,即它将 self 的副本保存为另一个 strong 指针。这会增加指向对象的保留计数,并导致保留循环。

在第二种情况下,该 block 捕获 me,即它将 me 的副本保存为另一个 weak 指针。这不会增加保留计数,因此不会导致保留周期。

(如果你在 block 的外部和内部打印地址,你会看到 地址不同。该 block 有自己指向对象的弱指针。)

如果指向的对象被释放,所有的弱引用(包括被 block )被 Objective-C 运行时设置为 nil

(我只希望我做对了。)

关于ios - ARC __block 和 __weak,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17812672/

相关文章:

iphone - 如何使这个应用程序屏幕滚动?

ios - objc 如何更改 UICollectionView 中第一行单元格的颜色?

ios - Swift/SpriteKit 多重碰撞检测?

ios - 在节中设置的标题下添加 View

ios - 内存泄漏 iOS(UIImageView、UIImage、CGImage)未在 ARC 上释放

ios - 在锁定屏幕上显示通知

ios - UIView 和 ScrollView 之间的 UIView 过渡翻转

iphone - "Incompatible pointer to integer conversion"使用方 block 时

delphi - 使用 ARC 与不使用 ARC 释放接口(interface)对象 - Delphi

memory-leaks - 与编译时ARC相比,运行时GC有何优势?