我知道阻止的最佳做法就是那样
__weak SomeObjectClass *weakSelf = self;
SomeBlockType someBlock = ^{
SomeObjectClass *strongSelf = weakSelf;
if (strongSelf == nil) {
// The original self doesn't exist anymore.
// Ignore, notify or otherwise handle this case.
}
[self someMethod];
};
我理解使用 weakSelf 用于防止保留周期,并且在weakSelf可能为零的情况下使用 strongSelf 。 但我只是想知道使用 strongSelf 会再次导致保留周期,因为块捕获并保留strongSelf和strongSelf也是自我的指针。 有人可以给我一个解释,谢谢。
答案 0 :(得分:1)
问问自己:strongSelf存在多久了?
strongSelf仅在块执行时才存在。所以基本上,它在someMethod正在执行时拥有强大的参考,而不再是。
我认为你的意思是
[strongSelf someMethod];
而不是
[self someMethod];
因为前者强烈引用 strongSelf (等于self),而块执行,而后者将强烈引用 self ,阻止存在。
答案 1 :(得分:0)
您可以使用生命周期限定符来避免强引用周期。对于 例如,通常如果你有一个排列在一个对象的图形 亲子等级和父母需要引用他们的孩子和 反之亦然,那么你就使父母与子女的关系变得强大 孩子与父母的关系薄弱。其他情况可能更多 微妙的,特别是当它们涉及块状物体时。*
在手动引用计数模式下,__ _block id x;有没有效果 保留x。在ARC模式下,__block id x;默认为保留x(只是 像所有其他值一样)。获得手动引用计数模式 在ARC下的行为,你可以使用__unsafe_unretained __block id x;。 正如名称__unsafe_unretained暗示的那样,有一个 非保留变量是危险的(因为它可以悬挂)并且是 因此气馁。两个更好的选择是使用__weak(如果 你不需要支持iOS 4或OS X v10.6),或者设置__block 值为零以打破保留周期。
如果你需要在一个块中捕获self,比如在定义一个时 回调块,考虑内存管理很重要 影响。
Blocks保持对任何捕获对象的强引用,包括 自我,这意味着很容易得到一个强大的参考 周期
至于你的例子 - 那里没有保留周期,因为 CouchDeveloper 表示,因为块只会在执行时保持对self的引用。但是,无论你的__weak声明,如果我们将代码更改为:
__weak SomeObjectClass *weakSelf = self;
self.someBlock = ^{
SomeObjectClass *strongSelf = weakSelf;
if (strongSelf == nil) {
// The original self doesn't exist anymore.
// Ignore, notify or otherwise handle this case.
}
[self someMethod];
};
现在我们有保留周期 - 我们引用了块和内部块我们引用了self。为避免这种情况,您应该使用__weak方法:
__weak SomeObjectClass *weakSelf = self;
self.someBlock = ^{
SomeObjectClass *strongSelf = weakSelf;
if (strongSelf == nil) {
// The original self doesn't exist anymore.
// Ignore, notify or otherwise handle this case.
} else {
[strongSelf someMethod];
}
};
更多文章: https://coderwall.com/p/vaj4tg
http://teohm.com/blog/2012/09/03/breaking-arc-retain-cycle-in-objective-c-blocks/
答案 2 :(得分:-1)
首先,你必须了解strongSelf的生命周期,它只存在于someBlock中,在someBlock完成后,strongSelf引用的对象将被释放。 当someBlock翻译成MRR时会喜欢这样:
^{
SomeObjectClass *strongSelf = [weakSelf retain];
if (strongSelf == nil) {
// The original self doesn't exist anymore.
// Ignore, notify or otherwise handle this case.
}
[self someMethod];
[strongSelf release];
};